Resources¶
Default Collection
and Item
resources are provided to easily provide endpoints for your schemas.
Each resource has the following features:
- Schema instances are passed into the resource for it to work on
- URI template is encapsulated in the resource
- Restricting the HTTP methods it will handle
- Changing the content types it will accept
- Custom error handlers for schema validation errors
A Collection
resource by default provides POST and GET handlers, with GET returning a JSON
list of the requested resource.
An Item
Using the Person
schema we created in the previous chapter, we can declare our resources:
from plume import Collection, Item
person = Person()
resources = (
Collection(person, '/people'),
Item(person, '/people/{name}')
)
With the resources ready, you can use a factory function to create a Falcon app:
from plume import create_app
# ``application`` is an instance of ``falcon.API``
application = create_app(resources)
All create_app
does is instantiate an app and call Falcons’ add_route
for each resource in the given list.
File Storage¶
Plume also provides basic FileCollection
and FileItem
resource classes, specifically intended
for serving and accepting file data.
As with Collection
and Item
resources, you can configure the uri template, allowed content types and
HTTP methods.
You also expected to pass a storage class to the resource. This is essentially the same as in the Falcon tutorial.
The storage class should provide save
, open
and list
methods.
save
and open
are fairly clear and are as explained in the falcon tutorial.
list
should return the URL’s of all available files in the store.
Plume provides a basic file store - plume.FileStore
which can be used.
All this makes it easy to add file handling. Expanding the resources example:
import os
from plume import Collection, Item, FileCollection, FileItem, FileStore
# Setup the storage
path = os.path.dirname(__file__)
store = FileStore(path)
person = Person()
resources = (
Collection(person, '/people'),
Item(person, '/people/{name}'),
FileCollection(store), # The uri_template argument defaults to ``/files``
FileItem(store)
)
Handling files in schemas¶
If you come from django, you might be expecting some sort of FileField
you can declare on a schema.
Plume does not provide this; This keeps your file storage logic completely separate from the rest of the app,
meaning you could potentially swap out your file store for a GridFS backed store, or switch to a completely
different service for hosting files.
I reccomend that you declare files as Url fields on your schema, with the relative=True
parameter set.
The other advantage over tighter coupling is that your file fields could simply be a URL to an entirely different website (e.g. some stock image provider, or a facebook profile picture).
There are disadvantages which we need to overcome:
- You now need to make 2 requests from a client. One to upload the file and one to update the resource with the file url.
- (It is a matter of some debate as to whether this should in fact be considered the best practice for REST API’s since
- multipart form data is not truly JSON or XML)
- Plume offers no validation or method by which to link a file upload to a subsequent patch request other than what the client tells it. E.g. imagine a client successfully uploads the file but the patch to update the resource with the new URL goes wrong. To overcome this, you could take a look at ‘Resumable Uploads’. We will be looking at whether Plume can provide any nice api to help with this in the future.