-
Notifications
You must be signed in to change notification settings - Fork 0
RESTful API
In order to facilitate cleaner code on the front end, we have started providing access to the database models through a RESTful API. There's a good three-part series [1] introducing REST for more information.
The endpoints are all prefixed with /rest/vX
where X is the version number for the REST interface. The most recent version is 1 (since we just started).
The available resources are:
Resource | Description |
---|---|
/rest/v1/needs/ |
The collection of needs. Use query parameters to access a collection of needs for a particular project. Anyone may read any needs, but only project administrators or site administrators may create new needs. |
/rest/v1/needs/ID |
A particular need identified by the key ID .
Anyone may read any need, but only project
administrators or site administrators may update
or delete a need. |
/rest/v1/needs/ID/volunteers/ |
The collection of volunteers for a given need. This may only be used to create a new volunteer at the moment. Only project members can create a new volunteer for themselves. |
In general, for a given model
, the endpoints are listed below. The HTTP method may either be specified as described; alternatively, for PUT
and DELETE
, send a POST
request with an additional parameter _method
A collection resource for a given model
can be accessed at the /model/
path. It represents the collection of model
objects in the system. Generally, you may either retrieve the collection (or a subset), or create a new item in the collection. Upon success, this resource will give a 200 OK
response.
-
GET
/model/
Get a list of
model
objects. The response will contain a representation of the identifiedmodel
objects. -
POST
/model/
Creates a new
model
object within the collection. The response will contain a representation of the createdmodel
object.
An instance resource for a given model
can be accessed at the /model/ID
path. It represents a particular model
object instance identified by ID
. Generally, you may retrieve details about the resource, make changes to the resource, or delete the resource. Upon success, this resource will return a 200 OK
status. If an instance identified by ID
does not exist, the resource will return a 404 Not Found
response. If multiple resources exist identified by ID
, the resource will return a 409 Conflict
response.
-
GET
/model/ID
Gets a
resource
identified byID
. The response will contain a representation of the identifiedmodel
object. -
PUT
/model/ID
Modify the
resource
identified byID
. The response will contain an updated representation of the identifiedresource
object. -
DELETE
/model/ID
Delete the
resource
identified byID
. The response will be empty.
All resources will return the following status codes on error:
-
403 Forbidden
if the current user does not have permission to perform the requested action -
405 Method not allowed
if an HTTP request method is supplied to a resource that does not support that method (e.g.PUT
for a collection).
Say you want to create resources based around projects (and collections of projects). Import the controllers.rest
module, and the giveaminute.models
module:
from controllers import rest from giveaminute import models
Assuming we have a model called models.Project
already (which we do), we can begin to make our resources. Say we want one resource for project collectir ons. We want to be able to retrieve collections and add new projects to them. We can construct the resource using a RestController
:
class ProjectCollectionResource (rest.ListInstancesMixin, rest.CreateInstanceMixin, rest.RestController): model = models.Project
We use two mixins here to give the resource controller the ability to list and create resources. The other mixins available from the controllers.rest
module are ReadInstanceMixin
, UpdateInstanceMixin
, and DeleteInstanceMixin
. Note that in the default implementation, the ReadInstanceMixin
and ListInstancesMixin
are mutually exclusive, as they will both be blindly mapped to the GET
method; you'll only ever get one behavior.
After you have created your controller, in the main
module add a couple of routes identifying your resources:
ROUTES = (... '^/rest/v1/projects/$', 'controllers.rest.ProjectCollectionResource', '^/rest/v1/projects/(\d+)/$, 'controllers.rest.ProjectInstanceResource', ...)
That's it!
By default a resource has full read-only permission restrictions. If you provide a CreateInstanceMixin
or a DeleteInstanceMixin
, then no one will be able to create or delete instances. Safe, but not very useful. Use rest.ResourceAccessRules
objects to differently allow and restrict access. For example, if you want your project resources to be read-only for everyone except administrative users, use the rest.NonAdminReadOnly
access rules:
class ProjectCollectionResource (rest.ListInstancesMixin, rest.CreateInstanceMixin, rest.RestController): model = models.Project access_rules = rest.NonAdminReadOnly()
ResourceAccessRules
classes implement permission checkers that operate on an instance of a user model (or None) and an arbitrary resource instance. The permission checking methods are:
-
can_read(user, instance)
Returns
True
if the user can read the resource -
can_create(user, instance)
Returns
True
if the user can store the resource -
can_update(user, instance)
Returns
True
if the user can modify the resource -
can_delete(user, instance)
Returns
True
if the user can delete the resource
These methods can be overridden in your own access rules class to create a custom rule system.
[1] |
A three-part series introducing REST: |