问题
I've been playing around with Google Cloud Endpoints for the past few days (aiming to hook it up with AngularJS) and I ran into a bit of trouble when I try to retrieve a single entity from my datastore.
My ndb
model setup is:
class Ingredients(EndpointsModel):
ingredient = ndb.StringProperty()
class Recipe(EndpointsModel):
title = ndb.StringProperty(required=True)
description = ndb.StringProperty(required=True)
ingredients = ndb.StructuredProperty(Ingredients, repeated=True)
instructions = ndb.StringProperty(required=True)
Here is the API method I've defined to retrieve the entity by 'title'
:
@Recipe.method(request_fields=('title',), path='recipe/{title}',
http_method='GET', name='recipe.get')
def get_recipe(self, recipe):
if not recipe.from_datastore:
raise endpoints.NotFoundException('Recipe not found.')
return recipe
The API method works fine if I were to use 'id'
(helper methods provided by EndpointsModel
) in place of 'title'
for the request fields. When I use 'title'
, however, I'm getting
404 Not Found
{"error_message": "Recipe not found.","state": "APPLICATION_ERROR"}
Can anyone point out if I am missing something somewhere?
NOTE: See comments. The error in the question used to read
400 Bad Request
{"error_message": "Error parsing ProtoRPC request (Unable to parse request content: Message RecipeProto_title is missing required field title)", "state": "REQUEST_ERROR"}
but @sentiki was able to resolve this previous error.
回答1:
The 404
is expected. The "magic" of the id
property is that it calls UpdateFromKey.
This method tries to set an ndb.Key
on the entity based on the request and then attempts to retrieve the entity stored with that key. If the entity exists, the values from the datastore are copied over to the entity parsed from the request and then the _from_datastore
property is set to True.
By using request_fields=('title',)
, you have a simple data property rather than an EndpointsAliasProperty and so only the values are set. As a result, _from_datastore
never gets set and your check
if not recipe.from_datastore:
raise endpoints.NotFoundException('Recipe not found.')
throws an endpoints.NotFoundException
as expected.
来源:https://stackoverflow.com/questions/16647111/error-when-trying-to-retrieve-a-single-entity