Revising the RestController docs
This commit is contained in:
@@ -0,0 +1,139 @@
|
|||||||
|
.. _rest:
|
||||||
|
|
||||||
|
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 | 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 |
|
||||||
|
+-----------------+--------------------------------------------------------------+--------------------------------------------+
|
||||||
|
|
||||||
|
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.
|
||||||
|
|||||||
@@ -218,72 +218,3 @@ requests ``/hello.json``. The second tells the templating engine to use
|
|||||||
tells Pecan to use the html_template.mako when the client requests
|
tells Pecan to use the html_template.mako when the client requests
|
||||||
``/hello.html``. If the client requests ``/hello``, Pecan will use the
|
``/hello.html``. If the client requests ``/hello``, Pecan will use the
|
||||||
text/html template.
|
text/html template.
|
||||||
|
|
||||||
.. _advanced_routing:
|
|
||||||
|
|
||||||
Advanced Routing
|
|
||||||
================
|
|
||||||
Pecan offers a few ways to control and extend routing.
|
|
||||||
|
|
||||||
|
|
||||||
.. _restcontroller:
|
|
||||||
|
|
||||||
RestController
|
|
||||||
--------------
|
|
||||||
A Decorated Controller that dispatches in a RESTful Manner.
|
|
||||||
|
|
||||||
This controller was designed to follow Representational State Transfer protocol, also known as REST.
|
|
||||||
The goal of this controller method is to provide the developer a way to map
|
|
||||||
RESTful URLS to controller methods directly, while still allowing Normal Object Dispatch to occur.
|
|
||||||
|
|
||||||
Here is a brief rundown of the methods which are called on dispatch along with an example URL.
|
|
||||||
|
|
||||||
+-----------------+--------------------------------------------------------------+--------------------------------------------+
|
|
||||||
| Method | Description | Example Method(s) / URL(s) |
|
|
||||||
+=================+==============================================================+============================================+
|
|
||||||
| get_one | Display one record. | GET /movies/1 |
|
|
||||||
+-----------------+--------------------------------------------------------------+--------------------------------------------+
|
|
||||||
| get_all | Display all records in a resource. | GET /movies/ |
|
|
||||||
+-----------------+--------------------------------------------------------------+--------------------------------------------+
|
|
||||||
| get | A combo of get_one and get_all. | GET /movies/ |
|
|
||||||
| | +--------------------------------------------+
|
|
||||||
| | | GET /movies/1 |
|
|
||||||
+-----------------+--------------------------------------------------------------+--------------------------------------------+
|
|
||||||
| new | Display a page to prompt the User for resource creation. | GET /movies/new |
|
|
||||||
+-----------------+--------------------------------------------------------------+--------------------------------------------+
|
|
||||||
| edit | Display a page to prompt the User for resource modification. | GET /movies/1/edit |
|
|
||||||
+-----------------+--------------------------------------------------------------+--------------------------------------------+
|
|
||||||
| post | Create a new record. | POST /movies/ |
|
|
||||||
+-----------------+--------------------------------------------------------------+--------------------------------------------+
|
|
||||||
| put | Update an existing record. | POST /movies/1?_method=PUT |
|
|
||||||
| | +--------------------------------------------+
|
|
||||||
| | | PUT /movies/1 |
|
|
||||||
+-----------------+--------------------------------------------------------------+--------------------------------------------+
|
|
||||||
| post_delete | Delete an existing record. | POST /movies/1?_method=DELETE |
|
|
||||||
| | +--------------------------------------------+
|
|
||||||
| | | DELETE /movies/1 |
|
|
||||||
+-----------------+--------------------------------------------------------------+--------------------------------------------+
|
|
||||||
| get_delete | Display a delete Confirmation page. | GET /movies/1/delete |
|
|
||||||
+-----------------+--------------------------------------------------------------+--------------------------------------------+
|
|
||||||
| delete | A combination of post_delete and get_delete. | GET /movies/delete |
|
|
||||||
| | +--------------------------------------------+
|
|
||||||
| | | DELETE /movies/1 |
|
|
||||||
| | +--------------------------------------------+
|
|
||||||
| | | DELETE /movies/ |
|
|
||||||
| | +--------------------------------------------+
|
|
||||||
| | | POST /movies/1/delete |
|
|
||||||
| | +--------------------------------------------+
|
|
||||||
| | | POST /movies/delete |
|
|
||||||
+-----------------+--------------------------------------------------------------+--------------------------------------------+
|
|
||||||
|
|
||||||
You may note the ?_method on some of the URLs. This is basically a hack because exiting browsers
|
|
||||||
do not support the PUT and DELETE methods. Just note that if you decide to use a this resource with a web browser,
|
|
||||||
you will likely have to add a _method as a hidden field in your forms for these items. Also note that RestController differs
|
|
||||||
from a base Pecan controller in that it offers no index, default, or lookup. It is intended primarily for resource management.
|
|
||||||
|
|
||||||
|
|
||||||
.. _note:
|
|
||||||
The following items are still pending:
|
|
||||||
|
|
||||||
* Hooks
|
|
||||||
* Security
|
|
||||||
|
|||||||
Reference in New Issue
Block a user