Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

google cloud endpoint method with multiple response message

I have a google could enpoint method that I need to be able to return either a MaleResponseMessage or a FemaleResponseMessage. Is there a way to specify that such as with

@endpoints.method(message_types.VoidMessage, [MaleResponseMessage, FemaleResponseMessage])

There is of course the option of declaring a super message class, say, PersonResponseMessage to wrap either MaleResponseMessage or FemaleResponseMessage. But is there something similar to the snippet above?

EDIT:

Trying to implement my own proposal, I got stuck. The only thing the two message types have in common is the request: the exact same request fields (with an additional boolean female=true/false) for PersonRequest. The MaleResponseMessage and the FemaleResponseMessage have no field in common. So I am using one endpoint method, as @bossylobster shows, where I check

if request.female : # request.female == True
    return get_female(etc, etc)
else: # request.female == False // implies male
    return get_male(etc,etc)

For the response, I need something like

class PersonResponse(messages.Message):
  if ??? :
     item = messages.MessageField(MaleResponseMessage,1)
  else:
      item = messages.MessageField(FemaleResponseMessage,1)

I am not sure what to check ??? for. First, I thought about isinstance or type. But how would I do that? Would the below work?

class PersonResponse(messages.Message):
  if type(Message()) == MaleResponseMessage :
     item = messages.MessageField(MaleResponseMessage,1)
  else:
      item = messages.MessageField(FemaleResponseMessage,1)
like image 628
Katedral Pillon Avatar asked Mar 20 '13 16:03

Katedral Pillon


1 Answers

Unfortunately no. You can have only one response and one request schema; this is because they are registered with Google's API infrastructure and having a strict schema is what provides the speed and efficiency of requests.

Your best bet would be to combine the fields needed for each male and female into a single model class and do your own validation.

A possible solution could look like

from protorpc import messages

class Gender(messages.Enum):
    MALE = 0
    FEMALE = 1

class GenderRequest(messages.Enum):
    gender = messages.EnumField(Gender, 1, required=True)

class PersonResponse(messages.Message):
    gender = messages.EnumField(Gender, 1)
    # shared fields
    # female specific fields
    # male specific fields

and then in your actual method

    @endpoints.method(GenderRequest, PersonMessage, ...)
    def my_method(self, request):
      if request.gender == Gender.MALE:
          return male_response(request)
      elif request.gender == Gender.FEMALE:
          return female_response(request)
      else:
          # This should never occur since gender is required
          raise endpoints.BadRequestException('Gender not set.')

where male_response and female_response are methods which create instances of PersonMessage corresponding to male and female.

like image 55
bossylobster Avatar answered Nov 12 '22 09:11

bossylobster