简而言之,您的Cloud Endpoints API 是您的应用程序。一些关于云端点的文档可能有点混乱(或模糊),但在服务器端,它本质上是一堆Python装饰器或Java注释,它们允许您将应用程序逻辑作为REST API公开。
我发现云端点的Java实现比Python更直观,这需要更多的工作来对对象进行序列化。你可以看看endpoints_proto_datastore.ndb.EndpointsModel
这可能会从方程式(定义信息)中拿出一些样板材料。
基本上,当你编写你的API时,每个端点映射到一个python函数。内部的功能,你可以做你喜欢的东西,但通常这将是两种:
Deserialise您发布的JSON,验证它,并写一些实体数据存储(或云SQL,BigTable的,别的地方)。
从Datastore读取一个或多个实体,并将它们序列化为JSON并将它们返回给客户端。
例如,你可以定义你的API(端点功能全集合)作为
@endpoints.api(name='cafeApi', version='v1', description='Cafe API', audiences=[endpoints.API_EXPLORER_CLIENT_ID])
class CafeApi(remote.Service):
# endpoints here
例如,你可能有一个端点,以得到附近的咖啡馆:
@endpoints.method(GEO_RESOURCE, CafeListResponse, path='cafes/nearby', http_method='GET', name='cafes.nearby')
def get_nearby_cafes(self, request):
"""Get cafes close to specified lat,long"""
cafes = list()
for c in search.get_nearby_cafes(request.lat, request.lon):
cafes.append(c.response_message())
return CafeListResponse(cafes=cafes)
这里有几件事需要强调。使用Python端点实现,您需要定义资源和消息类 - 这些类用于封装请求数据和响应主体。
所以,在上面的例子中,GEO_RESOURCE
封装做出GeoPoint
所需的字段(这样我们就可以使用搜索API的位置进行搜索,但你可能只是搜索数据存储与一个5星评级咖啡馆):
GEO_RESOURCE = endpoints.ResourceContainer(
message_types.VoidMessage,
lat=messages.FloatField(1, required=True),
lon=messages.FloatField(2, required=True)
)
和CafeListResponse
只想封装CafeResponse对象list
(与云端点返回一个对象):
class CafeListResponse(messages.Message):
locations = messages.MessageField(CafeResponse, 1, required=False, repeated=True)
其中CafeResponse
是消息,该消息定义您希望如何通过API序列化对象(通常是数据存储实体)。例如,
class LocationResponse(messages.Message):
id = messages.StringField(1, required=False)
coordinates = messages.MessageField(GeoMessage, 3, required=True)
name = messages.StringField(4, required=False)
随着该端点的签名,可以通过HTTP GET
在/cafeApi/v1/cafes/nearby?lat=...&lon=...
或者通过,比如用`cafeApi.cafes.nearby(...)访问它,JavaScript的API客户端。
就我个人而言,我发现Flask在使用Python创建REST API方面更加灵活。
Hi @ tx802,非常感谢您的深入分析!我比Python更了解Java,但是我已经感到Python中的存储库比Java更多(即使我发现后者稍微更直观一些,表明它有更多支持/受欢迎程度)。使用这两者中的任何一个有什么优势? – neX
这肯定有帮助 - 我想我明白云端点现在应该做什么! – neX