Pecan — Overview
文章目录Pecan@expose()路由使用通用Controller写API使用RestController写APIPecanPecan是一个提供对象分派式路由 (object-dispatch style routing) 的轻量级 web 框架。尽管它很轻巧,但 Pecan 确实提供了广泛的功能集,可用于构建基于 HTTP 的应用程序,包括:Object-dispatch for easy r
Pecan
Pecan是一个提供对象分派式路由 (object-dispatch style routing) 的轻量级 web 框架。
尽管它很轻巧,但 Pecan 确实提供了广泛的功能集,可用于构建基于 HTTP 的应用程序,包括:
-
Object-dispatch for easy routing
-
Full support for REST-style controllers
-
Extensible security framework
-
Extensible template language support
-
Extensible JSON support
-
Easy Python-based configuration
@expose()
如果一个方法被@expose()
装饰,那么Pecan会将相应的请求路由到这个方法。
示例:
from pecan import expose
class RootController(object):
@expose('json')
def hello(self):
return {'msg': 'Hello!'}
当访问/hello
时,会返回{'msg': 'Hello!'}
给客户端。
@expose的参数 “json”,指定content_type
为application/json
。如果不指定,content_type
默认是text/html
。
路由
Pecan 使用称为对象分发(object-dispatch)的路由策略(routing strategy)将 HTTP 请求映射到控制器,然后将方法回调。对象分发首先将路径拆分为组件列表,然后从根控制器开始遍历对象路径。
示例:
from pecan import expose
class BooksController(object):
@expose()
def index(self):
return "Welcome to book section."
@expose()
def bestsellers(self):
return "We have 5 books in the top 10."
class CatalogController(object):
@expose()
def index(self):
return "Welcome to the catalog."
books = BooksController()
class RootController(object):
@expose()
def index(self):
return "Welcome to store.example.com!"
@expose()
def hours(self):
return "Open 24/7 on the web."
catalog = CatalogController()
在线商店对 /catalog/books/bestsellers
的请求分为 catalog
,books
和 bestsellers
。接下来,Pecan 将在根控制器上查找 catalog
。然后在 catalog
对象中查找 books
,最终在books
中找到 bestsellers
方法。
路径:
└── /
├── /hours
└── /catalog
└── /catalog/books
└── /catalog/books/bestsellers
根据路径路由到以下控制器方法:
└── RootController.index
├── RootController.hours
└── CatalogController.index
└── BooksController.index
└── BooksController.bestsellers
使用通用Controller写API
在下面的示例中,使用普通的Python对象创建controller。
当GET /
请求进来时,会路由到RootController
的index
方法。而这个index
方法被@expose(generic=True, template='json')
装饰,在expose内部生成@index.when
。此时,如果请求路径相同,但是请求方法不同,那么Pecan会根据请求方法将请求路由到相应的被@index.when
装饰的方法。
from pecan import abort, expose
# Note: this is *not* thread-safe. In real life, use a persistent data store.
BOOKS = {
'0': 'The Last of the Mohicans',
'1': 'Catch-22'
}
class BookController(object):
def __init__(self, id_):
self.id_ = id_
assert self.book
@property
def book(self):
if self.id_ in BOOKS:
return dict(id=self.id_, name=BOOKS[self.id_])
abort(404)
# HTTP GET /<id>/
@expose(generic=True, template='json')
def index(self):
return self.book
# HTTP PUT /<id>/
@index.when(method='PUT', template='json')
def index_PUT(self, **kw):
BOOKS[self.id_] = kw['name']
return self.book
# HTTP DELETE /<id>/
@index.when(method='DELETE', template='json')
def index_DELETE(self):
del BOOKS[self.id_]
return dict()
class RootController(object):
@expose()
def _lookup(self, id_, *remainder):
return BookController(id_), remainder
# HTTP GET /
@expose(generic=True, template='json')
def index(self):
return [dict(id=k, name=v) for k, v in BOOKS.items()]
# HTTP POST /
@index.when(method='POST', template='json')
def index_POST(self, **kw):
id_ = str(len(BOOKS))
BOOKS[id_] = kw['name']
return dict(id=id_, name=kw['name'])
使用RestController写API
Pecan提供RestController
,开发者可以继承这个类来创建controller。
from pecan import expose
from pecan.rest import RestController
from mymodel import Book
class BooksController(RestController):
@expose()
def get(self, id):
book = Book.get(id)
if not book:
abort(404)
return book.title
RestController
提供如下的映射。
例如:GET /books/1
请求会路由到get_one
方法。
Method | Description | Example Method(s) / URL(s) |
---|---|---|
get_one | Display one record. | GET /books/1 |
get_all | Display all records in a resource. | GET /books/ |
get | A combo of get_one and get_all. | GET /books/ GET /books/1 |
new | Display a page to create a new resource. | GET /books/new |
edit | Display a page to edit an existing resource. | GET /books/1/edit |
post | Create a new record. | POST /books/ |
put | Update an existing record. | POST /books/1?_method=put |
PUT /books/1 | ||
get_delete | Display a delete confirmation page. | GET /books/1/delete |
delete | Delete an existing record. | POST /books/1?_method=delete DELETE /books/1 |
如果需要自定义方法可以定义_custom_actions
。
如下示例:请求POST /books/checkout
会路由到BooksController
的checkout
方法。
from pecan import expose
from pecan.rest import RestController
from mymodel import Book
class BooksController(RestController):
_custom_actions = {
'checkout': ['POST']
}
@expose()
def checkout(self, id):
book = Book.get(id)
if not book:
abort(404)
book.checkout()
更多推荐
所有评论(0)