使用示例:
#author:[email protected]
import wsgiref.handlers
from google.appengine.ext import webapp
from rest import *
class CommentResource(RestResource):
def initialize(self):
self.response.out.write("comment.initialize:format=%s<br/>" %(self.format))
def index(self, entry_id):
self.response.out.write("comment.index:entry_id=%s<br/>" % entry_id)
def show(self, id, entry_id):
self.response.out.write("comment.show:id=%s,entry_id=%s<br/>" %(id, entry_id))
def create(self, entry_id):
self.response.out.write("comment.show:id=%s,entry_id=%s<br/>" %(id, entry_id))
def update(self, id, entry_id):
self.response.out.write("comment.update:id=%s,entry_id=%s<br/>" %(id, entry_id))
def delete(self, id, entry_id):
self.response.out.write("comment.delete:id=%s,entry_id=%s<br/>" %(id, entry_id))
class EntryResource(RestResource):
def initialize(self):
self.response.out.write("entry.initialize:format=%s<br/>" %(self.format))
def index(self):
self.response.out.write("entry.index<br/>")
def show(self, id):
self.response.out.write("entry.show:id=%s<br/>" %(id))
def create(self):
self.response.out.write("entry.show:id=%s<br/>" %(id))
def update(self, id):
self.response.out.write("entry.update:id=%s<br/>" %(id))
def delete(self, id):
self.response.out.write("entry.delete:id=%s<br/>" %(id))
""""""
def main():
RestHandler.route = {
'/entries' : EntryResource,
'/entries/:entry_id/comments' : CommentResource}
application = webapp.WSGIApplication([(".*", RestHandler)], debug=True)
wsgiref.handlers.CGIHandler().run(application)
if __name__ == '__main__':
main()
在这个rest实现机制中,资源支持的操作有5种,index,show,create,update,delete。
请求会根据请求的http method和路由设定自动和资源绑定。
比如
'/entries/:entry_id/comments' : CommentResource
这个路由说明 /entries/:entry_id/comments 这个模式的url将绑定到CommentResource上,
其中:entry_id是一个参数。
配置这个路由后,访问
/entries/2/comments 将调用CommentResource的index(self, entry_id)方法,里面的entry_id与路由配置的:entry_id是对应的,这里entry_id=2
同样
/entries/2/comments/1 将调用CommentResource的show(self, id, entry_id)方法,调用时候id=1,entry_id=2
该实现还支持不同的内容格式请求的区分,
/entries/2/comments/1
/entries/2/comments/1.html
/entries/2/comments/1.xml
这三个请求都将调用CommentResource的show(self, id, entry_id)方法,在这个方法中,可以通过self.format来获取用户所请求的格式,上面三个请求的内容格式分别为 html, html, xml
文件rest.py,实现url的解析及和资源的绑定
#author:[email protected]
import wsgiref.handlers
from google.appengine.ext import webapp
_DEFAUT_RESOURCE_FORMAT = 'html'
class RestResource:
def __init__(self, request, response, params = {}, value = None, format = _DEFAUT_RESOURCE_FORMAT):
self.request = request
self.response = response
self.params = params
self.value = value
self.format = format
def initialize(self):
""""""
def index(self, *args):
""""""
def show(self, res, *args):
""""""
def create(self, *args):
""""""
def update(self, res, *args):
""""""
def delete(self, res, *args):
""""""
class RestHandler(webapp.RequestHandler):
route = {}
#{
# '/':IndexResource,
# '/entries' : EntryResource,
# '/entries/:entry_id/comments' : CommentResource}
def __init__(self):
self.resource = None
def initialize(self, request, response):
webapp.RequestHandler.initialize(self, request, response)
if self.request.path == '' or self.request.path == '/':
self.resource = RestHandler.route['/'](request, response)
else:
self.resource = RestHandler.get_rest_resource(request, response)
if self.resource != None:
self.resource.initialize()
else:
self.error(404)
@staticmethod
def get_rest_resource(request, response):
path_fields = request.path[1:].split("/")
resource = None
resource_paramters = {}
resource_value = None
resource_format = _DEFAUT_RESOURCE_FORMAT
for item in RestHandler.route.items():
resource = None
resource_value = None
resource_paramters.clear()
resource_format = _DEFAUT_RESOURCE_FORMAT
route_path = item[0][1:]
route_path_fields = route_path.split("/")
if len(route_path_fields) == len(path_fields) or len(route_path_fields) + 1 == len(path_fields):
resource = item[1]
for i in range(len(path_fields)):
if i == len(path_fields) - 1 and path_fields[i].find(".") != -1:
arr = path_fields[i].split('.')
path_fields[i] = arr[0]
resource_format = arr[1]
if i == len(route_path_fields):
resource_value = path_fields[i]
elif path_fields[i] == route_path_fields[i]:
continue
elif route_path_fields[i].startswith(":"):
resource_paramters[route_path_fields[i][1:]] = path_fields[i]
else:
resource = None
break
if resource != None:
break;
if resource == None:
return None
else:
return resource(request, response, resource_paramters, resource_value, resource_format)
def get(self):
if self.resource != None:
if self.resource.value != None:
self.resource.show(self.resource.value, **self.resource.params)
else:
self.resource.index( **self.resource.params)
def post(self):
"""Handler method for POST requests."""
if self.resource != None:
if self.resource.value != None:
self.resource.create( **self.resource.params)
else:
self.error(404)
def put(self):
if self.resource != None:
if self.resource.value != None:
self.resource.update(self.resource.vaue, **self.resource.params)
else:
self.error(404)
def delete(self):
if self.resource != None:
if self.resource.value != None:
self.resource.delete(self.resource.vaue, **self.resource.params)
else:
self.error(404)
完整代码见附件