6.6 KiB
REST Controller
If you need to write controllers to interact with objects, using the
RestController
may help speed things up. It follows the
Representational State Transfer Protocol, also known as REST, by routing
the standard HTTP verbs of GET, POST, PUT, and DELETE to individual
methods:
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
URL Mapping
By default, the RestController
routes as follows:
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 |
|
|
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 |
|
|
get_delete | Display a delete confirmation page. | GET /books/1/delete |
delete |
|
|
Pecan's RestController
uses the de-facto standard
?_method=
query string hack to work around the lack of
PUT/DELETE support in current browsers.
The RestController
still supports the
index
, _default
, and _lookup
routing overrides. If you need to override _route
, however,
make sure to call RestController._route
at the end of your
custom _route
method so that the REST routing described
above still occurs.
Nesting
RestController
instances can be nested so that child
resources get the parameters necessary to look up parent resources. For
example:
from pecan import expose
from pecan.rest import RestController
from mymodel import Author, Book
class BooksController(RestController):
@expose()
def get(self, author_id, id):
author = Author.get(author_id)
if not author_id:
abort(404)
book = author.get_book(id)
if not book:
abort(404)
return book.title
class AuthorsController(RestController):
books = BooksController()
@expose()
def get(self, id):
author = Author.get(id)
if not author:
abort(404)
return author.name
class RootController(object):
authors = AuthorsController()
Accessing /authors/1/books/2
would call
BooksController.get
with an author_id
of 1 and
id
of 2.
To determine which arguments are associated with the parent resource,
Pecan looks at the get_one
or get
method
signatures, in that order, in the parent controller. If the parent
resource takes a variable number of arguments, Pecan will hand it
everything up to the child resource controller name (e.g.,
books
in the above example).
Custom Actions
In addition to the default methods defined above, you can add
additional behaviors to a RestController
by defining a
special _custom_actions
dictionary. For example:
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()
Additional method names are the keys in the dictionary. The values are lists of valid HTTP verbs for those custom actions, including PUT and DELETE.