Understandig the rest API

The main functionality of pyrocumulus is easily create rest apis based on your mongoengine documents. In this section lets take closer look on how it works [1].

How does it work?

This is quite simple. Pyrocumulus has a special request handler, pyrocumulus.web.handlers.RestHandler. It get a mongoengine.Document as a parameter and creates a restful api for it with optional CORS support.

To use that, you need to map an url to pyrocumulus.web.handlers.RestHandler and associate it with a document. If your document has embedded documents, they also need to be mapped to urls, but using the pyrocumulus.web.handlers.EmbeddedDocumentHandler class. To easily url configuration, pyrocumulus has the pyrocumulus.web.urlmappers.DocumentURLMapper class, wich creates all urls needed, including urls to EmbeddedDocuments.

After your urls are done, you need to create an tornado.web.Application to use your urls. To package all that together, you can use the pyrocumulus.web.applications.RestApplication class. You just pass your documents as paramenters to it and everything else is created for you.

RestHandler

Lets start understading how pyrocumulus.web.handlers.RestHandler works. In order to use that, you need to associate a mongoengine.Document to that handler and map a URL to. Its done using the URLSpec object. Something like this:

>>> from pyrocumulus.web.handlers import RestHandler
>>> from myapp.models import MyDocument
>>> from tornado.web import URLSpec
>>> urlspec = URLSpec('/api/mydocument/(.*)', RestHandler, model=MyDocument)

When you map a URL to pyrocumulus.web.handlers.RestHandler, you get a rest api for your documet, supporting the following operations:

  • GET request to YOUR_DOCUMENT_URL or YOUR_DOCUMENT_URL + ‘get’ to retrieve a specific object from database. Like this:

    >>> params = {'id': '1232ua7d330akd0'}
    >>> requests.get('/api/mydocument/', params=params)
    
  • GET request to YOUR_DOCUMENT_URL + ‘list’ to list objects. You can use the page and max params to paginate the result and the order_by param for ordering that.

    >>> params = {'page': 1, 'max': 10, 'order_by': 'some_field'}
    >>> requests.get('/api/mydocument/list', params=params)
    
  • PUT request to YOUR_DOCUMENT_URL or POST request to YOUR_DOCUMENT_URL + ‘put’ to insert a new object into the database.

    >>> params = {'name': 'Some name', 'location': 'Somewhere'}
    >>> request.put('/api/mydocument/', params=params)
    
  • DELETE request to YOUR_DOCUMENT_URL or POST request to YOUR_DOCUMENT_URL + ‘delete’ to delete an object from database

    >>> params = {'id': 'a9982lsdfk34kd'}
    >>> requests.delete('/api/mydocument/', params=params)
    

If your document has embedded documents, they also need to be mapped, but using the pyrocumulus.web.handlers.EmbeddedDocumentHandler class.

>>> from pyrocumulus.web.handlers import EmbbeddeDocumentRestHandler
>>> from myapp.models import MyDocument, MyEmbeddedDocument
>>> from tornado.web import URLSpec
>>> urlspec = URLSpec('/api/mydocument/embeddedfield/(.*)',
                       EmbeddedDocumentRestHandler,
                       model=MyEmbeddedDocument, parent_doc=MyDocument)

In order to facilitate that, pyrocumulus has a pyrocumulus.web.urlmappers.DocumentURLMapper, which creates all URLSpecs to a Document, including its EmbeddedDocuments.

DocumentURLMapper

The pyrocumulus.web.urlmappers.DocumentURLMapper class gets a Document and a RequestHandler in its constructor. The instance of pyrocumulus.web.urlmappers.DocumentURLMapper then creates all needed urls to your api works.

>>> from pyrocumulus.web.urlmappers import DocumentURLMapper
>>> from pyrocumulus.web.handlers import RestHandler
>>> from myapp.models import MyDocument
>>> mapper = DocumentURLMapper(MyDocument, RestHandler)
>>> urls = mapper.urls

You can use the optional arguments url_prefix and url_name_prefix to control how urls and urls names are created.

Once we are done with our urls, we need to create a tornado.web.Application instance to be served by our tornado server. Like this:

>>> from tornado.web import Application
>>> app = Application(urls)

RestApplication

In the pyrocumulus tutorial we used the pyrocumulus.web.application.RestApplication class to create our main application. Its a subclass from tornado.web.Application that receives a list of models and creates url mappings for it. It receives an optional argument prefix to be used as url_prefix and url_name_prefix on DocumentURLMapper.

>>> from pyrocumulus.web.applications import RestApplication
>>> app = RestApplication(MyDocument, prefix='/myapp')

This is how the restapi was created automaticlly. But one thing still needs to be explanined. How the tornado server runs our application. This is done by the pyrocumulus.commands.runtornado.RunTornadoCommand command.

runtornado command

The runtornado command is invoked in the command line as:

$ python pyromanager.py runtornado

Its default behavrior is to take the application to run from pyrocumulus.web.applications.get_main_application(), but you can use the parameter –application to specify an application to be used.

That’s it.

[1]For a better understanding on how RequestHadler works, you should read the tornado documentation on RequestHadler here