我想避免为我的googleappengine应用程序的不同模型创建Google云端点api的样板代码。假设我有一个Post
、User
和{posts
、users
和{posts
资源编写了以下代码:
import endpoints
from protorpc import messages
from protorpc import message_types
from protorpc import remote
from blog.models import Post
from cloud_endpoints import WEB_CLIENT_ID, ANDROID_CLIENT_ID, IOS_CLIENT_ID, ANDROID_AUDIENCE
class PostMessage(messages.Message):
id = messages.StringField(1)
title = messages.StringField(2)
body = messages.StringField(3)
class PostMessageCollection(messages.Message):
post_messages = messages.MessageField(PostMessage, 1, repeated=True)
def post_to_message(post):
return PostMessage(
id=str(post.key()),
title=post.title,
body=post.body)
ID_RESOURCE = endpoints.ResourceContainer(
message_types.VoidMessage,
id=messages.StringField(1, variant=messages.Variant.STRING))
PUT_RESOURCE = endpoints.ResourceContainer(
PostMessage,
id=messages.StringField(1, variant=messages.Variant.STRING))
POST_RESOURCE = endpoints.ResourceContainer(Post)
@endpoints.api(name='posts',
version='v1',
allowed_client_ids=[WEB_CLIENT_ID, ANDROID_CLIENT_ID, IOS_CLIENT_ID],
audiences=[ANDROID_AUDIENCE])
class PostsApi(remote.Service):
"""List"""
@endpoints.method(message_types.VoidMessage,
PostMessageCollection,
path='/posts',
http_method='GET',
name='posts.listPosts')
def list(self, unused_request):
post_messages = []
for post in Post.all():
post_messages.append(post_to_message(post))
return PostCollection(post_messages=post_messages)
"""Get"""
@endpoints.method(ID_RESOURCE,
PostMessage,
path='/posts/{id}',
http_method='GET',
name='posts.getPost')
def get(self, request):
try:
return post_to_message(Post.get(request.id))
except (IndexError, TypeError):
raise endpoints.NotFoundException('Post %s not found.' % (request.id,))
"""Create"""
@endpoints.method(POST_RESOURCE,
message_types.VoidMessage,
path='/posts',
http_method='POST',
name='posts.createPost')
def create(self, request):
post = Post(title=request.title, body=request.body)\
post.put()
return message_types.VoidMessage()
"""Update"""
@endpoints.method(PUT_RESOURCE,
message_types.VoidMessage,
path='/posts/{id}',
http_method='POST',
name='posts.updatePost')
def update(self, request):
try:
post = Post.get(request.id)
post.title = request.title
post.body = request.body
return message_types.VoidMessage()
except (IndexError, TypeError):
raise endpoints.NotFoundException('Post %s not found.' % (request.id,))
"""Delete"""
@endpoints.method(ID_RESOURCE,
message_types.VoidMessage,
path='/posts/{id}',
http_method='DELETE',
name='posts.deletePost')
def delete(self, request):
try:
post = Post.get(request.id)
post.delete()
return message_types.VoidMessage()
except (IndexError, TypeError):
raise endpoints.NotFoundException('Post %s not found.' % (request.id,))
我可以复制/粘贴这段代码,将“Post”改为“Category”,并编辑PostMessage
、PostMessageCollection
和{PostAPI
、CategoryAPI
和{Post
、PostMessage
、PostMessageCollection
、post_to_message
和资源路径(“/posts”、“/categories”和“/users”),这样我就不必为每个资源复制/粘贴类了吗?类将具有相同的方法和相同的修饰符,我不想对每个资源重复这一点。我使用python2.7。在
这条线已经用了两年了,但无论如何我还是要提出一个想法。它有一个明显的缺陷;下面将详细介绍。在
我假设您正在通过ndbapi使用数据存储。在
其想法是引入通用消息类(}类:
EntityContainer
,EntityContainerList
),它可以包含任何应用程序特定消息类的实例,并包含一个字典,将路由映射到protorpc
和{模型.py
主.py
^{pr2}$当然,也可以使用}方法。在
DELETE
、PUT
和{您拥有的消息类越有用,这种方法可以为您节省的代码越多。(我刚刚包含了两个
Book
和Movie
作为演示。)上面提到的缺陷是,
EntityContainer
类中的消息字段太多,任何类实例都只使用其中两个字段。我不知道事情在幕后是如何运作的,所以我无法评估这件事的严重性。在不幸的是,这个问题也不可能。方法装饰器需要请求描述(
PostMessageCollection
这里)。子类化message.Message
的请求描述不允许通过继承重用,因此所有的消息类都必须在没有任何继承的情况下完整地定义。在不过,我现在还不能达到这样的程度:
显然,这并不能节省多少时间。在
相关问题 更多 >
编程相关推荐