`

Restful your google app engine applications

阅读更多
使用示例:
#author:pickerel@gmail.com
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:pickerel@gmail.com
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)




完整代码见附件
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics