简而言之,您的 Cloud Endpoints API 就是您的应用程序。一些有关 Cloud Endpoints 的文档可能有点混乱(或含糊不清),但在服务器端,它本质上是一堆 Python 装饰器或 Java 注释,允许您将应用程序逻辑公开为 REST API。
我发现 Cloud Endpoints 的 Java 实现比 Python 更直观,后者需要更多的工作来(反)序列化您的对象。您可以查看endpoints_proto_datastore.ndb.EndpointsModel,它可能会排除一些样板文件(定义消息)。
基本上,当您编写 API 时,每个端点都会映射到一个 python 函数。在该函数中,您可以做任何您喜欢的事情,但通常是:
反序列化您的 POST JSON,对其进行验证,然后将一些实体写入 Datastore(或 Cloud 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 Endpoints 实现,您需要定义资源和消息类 - 它们用于封装请求数据和响应主体。
因此,在上面的示例中,GEO_RESOURCE 封装了创建 GeoPoint 所需的字段(因此我们可以使用 Search API 按位置搜索,但您可能只搜索 Datastore 以获取 5 星评级的咖啡馆):
GEO_RESOURCE = endpoints.ResourceContainer(
message_types.VoidMessage,
lat=messages.FloatField(1, required=True),
lon=messages.FloatField(2, required=True)
)
而CafeListResponse 只会封装一个 list 的 CafeResponse 对象(使用 Cloud Endpoints 您返回单个对象):
class CafeListResponse(messages.Message):
locations = messages.MessageField(CafeResponse, 1, required=False, repeated=True)
CafeResponse 是定义您希望您的对象(通常是 Datastore 实体)如何被您的 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=... 或通过 Javascript API 客户端使用 `cafeApi.cafes.nearby(...) 访问它。
就我个人而言,我发现 Flask 使用 Python 创建 REST API 更加灵活。