4.7 KiB
Routing
When a user requests a Pecan-powered page how does Pecan know which controller to use? Pecan uses a method known as Object-dispatch to map a HTTP request to a controller. Obejct-dispatch begins by spliting the path into a list of components and then walking object path starting at the root controller. Let's look at a simple store application: :
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()
A request for /catalog/books/bestsellers from the online
store would begin by Pecan breaking the request up into
catalog, books, and bestsellers.
Next, Pecan would then lookup catalog on the root
controller. Using the catalog object, Pecan would then
lookup books followed by bestsellers. What if
the URL ends in a slash? Pecan will check for an index
method on the current object. In the example above, you may have noticed
the expose decorator.
Routing Algorithm
_lookup
- ::
from pecan import expose
from mymodel import get_student_by_name
- class StudentController(object):
- def __init(self, person):
self.student = student
@expose() def name(self): return self.student.name
- class ClassController(object):
@expose() def _lookup(self, name, *remainder): student = get_student_by_name(name) if student: return StudentController(student, remainder) else: abort(404)
_default
- ::
from pecan import expose
- class RootController(object):
@expose() def hello(self): return 'hello'
@expose(): def bonjour(self): return 'bonjour'
@expose(): def _default(self): return 'I cannot say hi in that language'
_route
- ::
from pecan import expose
Controller Args
- ::
from pecan import expose
- class RootController(object):
@expose() def say(self, msg): return msg
Client requests /say/hi the controller returns "hi".
:: from pecan import expose
- class RootController(object):
@expose(): def say(self, msg=None): if msg is None: return "I not sure what to say" else: return msg
Client requests /say?msg=hello the controller returns
"hello".
Generic Functions
- ::
from pecan import expose
- class RootController(object):
@expose(generic=True) def index(self): pass
@index.when(method='POST'): def index_post(self): pass
@index.when(method='GET'): def index_get(self): pass
Helper Functions
redirect abort
@expose
At its core, expose is how you tell Pecan which methods
in a class are controllers. expose accepts eight optional
parameters some of which can impact routing. :
def expose(template = None,
content_type = 'text/html',
schema = None,
json_schema = None,
variable_decode = False,
error_handler = None,
htmlfill = None,
generic = False):
Let's look at an example using template and content_type:
from pecan import decorators
class RootController(object):
@expose('json')
@expose('text_template.mako', content_type='text/plain')
@expose('html_template.mako')
def hello(self):
return {'msg': 'Hello!'}
You'll notice that we used three expose decorators. The first tells
Pecan to serialize dict using JSON serialization when the
client requests /hello.json. The second tells the
templating engine to use text_template.mako when the client
request /hello.txt. The third tells Pecan to use the
html_template.mako when the client requests /hello.html. If
the client requests /hello, Pecan will use the text/html
template.
Advanced Routing
Hooks Security REST Controller