Common Patterns =============== This section contains some approaches to common problems. If you have a recommedation, please feel free to reach out to us. Adding extra information to messages ------------------------------------ Sometimes you want additional information to go along with your model data, here's a quick example:: import ferris3 as f3 import endpoints import protopigeon from protorpc import messages from google.appengine.ext import ndb # This is our example model. # it has two basic properties plus one method that provides # some extra information. class Page(ndb.Model): title = ndb.StringProperty() content = ndb.TextProperty() def get_permissions(): if endpoints.get_current_user().email() == 'admin@example.com': return ["read", "update", "delete"] else: return ["read"] # We'll create a standard message for our Model. This will have # the title and content fields. PageMessage = f3.messages.model_message(Page) # We'll use this message to hold the permissions. class WithPermissions(messages.Message): permissions = messages.StringField(1, repeated=True) # We'll use protopigeon to combine the two messages together. # This message will have title, content, and permissions fields. PageMessageWithPermissions = protopigeon.compose(PageMessage, WithPermissions) @f3.auto_service class PagesService(f3.Service): @f3.auto_method(returns=PageMessageWithPermissions) def get(self, request, id=(str,)): page = f3.ndb.get(id) if not page: raise f3.NotFoundException() # We serialize as usual using the combined message. # The serialization will handle the title and content fields. message = f3.messages.serialize(PageMessageWithPermissions, page) # Finally, we'll manually populate the permissions field. message.permissions = page.get_permissions() return message Using custom properties with protopigeon ---------------------------------------- Sometimes it's desired to use a custom property or to override the built-in behavior for serializing properties. Here's an example:: import ferris3 import endpoints import protopigeon from protorpc import messages from google.appengine.ext import ndb # This is our custom property class. # We want ferris / protopigeon to automatically # serialize this in messages class ExampleProperty(ndb.StringProperty): def _to_base_type(self, value): return "---" + str(value) + "---" def _from_base_type(self, value): return value.strip('-') # A simple class that uses our custom property class ExampleModel(ndb.Model): normal = ndb.StringProperty() custom = ExampleProperty() # This converter will tell ferris / protopigeon how to # handle our custom property. class ExamplePropertyConverter(protopigeon.converters.Converter): @staticmethod def to_field(Model, property, count): return messages.StringField(count, repeated=property._repeated, required=property._required) # This tells protopigeon about our converter. protopigeon.converters.converters["ExampleProperty"] = ExamplePropertyConverter # Everything else happens automatically. @ferris3.auto_service class CustomService(ferris3.Service): list = ferris3.hvild.list(ExampleModel) insert = ferris3.hvild.insert(ExampleModel)