RESTful Django practice

djangopythonrestful

After several rounds reading RESTfull Web Services, I still have feeble confidence on my understanding the hyped REST idea, so please never hesitate to criticize, suggest in the comment.

Expose the resources

A book can be easily be identified by ISBN or EAN, however, it may stand for the specific book other than other books, or it refers an eBook instance to for content presentation. We use an additional argument, format to differentiate them:

/bookshelf/books/(isbn|ean)?format=(pdf|chm|...|json)

UPDATE A better approach is to use the pseudo file:

/bookshelf/books/(isbn|ean)(.(pdf|chm|...|json))

The default format is JSON, the server will render the meta data and available eBook formats in JSON.

Client request Server response
GET ../isbn(.pdf) Book meta data and available formats, or the eBook data.
  • 404/Not Found if the book does not exists
PUT ../isbn
  • 201/Created if the server create a new Book instance
  • 200/OK if the book exists
  • 400/Bad Request if the ISBN is invalid.
PUT ../isbn.pdf
  • 201/Created if the specified format eBook does not exist.
  • 200/OK if the eBook exists. The admin needs to moderate later.
  • 400/Bad Request if the ISBN is invalid.
HEAD ../isbn Available formats.(obsolete)
  • 404/Not Found if the book does not exists.
HEAD ../isbn.pdf The content length and other information about the file.
  • 404/Not Found if the book does not exists.
DELETE ../isbn
  • 200/Accepted Remove the Book instance if no related eBook exists.
  • 404/Not Found if the book does not exists.
  • 409/Conflict if there exist at least one eBook related.
DELETE ../isbn.pdf
  • 200/Accepted remove the eBook instance, the admin needs to moderate.
  • 404/Not Found if the book does not exists.

Furthermore, the URL representation is supposed to be discoverable. So we add two boring URL:

Client request Server response
GET /bookshelf/ Available list, currently only books supported.
GET /bookshelf/books All books with pagination, ?page=n

Serialization

There exists a generic RESTful Django project, django-rest-interface, no surprise it takes the built-in JSON serializer.

The default JSON serializer is convenient, but from my understanding, it is more or less gears towards the round trip of data serialization, while we favor presentation only:

  • Too much database details exposed to the end users.
  • ForeignKey and ManyToMany are interpreted as external link using the id field.

Furthermore, the JSON serializer is not lazy enough: the data has to be fetched from the database and stored in the memory before it is dumped to the stream. This may result in a serious scaling issue. The side-effect of the writing policy make it impossible to serialize in a recursive fashion, just because the stream has not been flushed until all the objects have been addressed. Otherwise, the ForeighKey and ManyToMany can be easily addressed. A better solution is to take the similar approach as SAX does. The tags are emitted recursively once a new object needs to be serialized.

We will discuss the Pattee’s implementation next time.