1

I am building a Backbone app which displays interactive facsimiles of diagrams from certain technical manuals. Each manual has a number of diagram types (say A-Z), distributed over its pages. Each diagram might occur more than once across the pages, and sometimes a single page might contain more than one instance of a given diagram type.

I have a Django backend serving a REST API which my frontend consumes. What I have been struggling with is the design of the url for the request. I have tried several patterns, none of which satisfy me. My Django model looks something like this:

class Diagram(models.Model):
    type = models.CharField(max_length=1)
    page = models.IntegerField(default=1)
    order = models.IntegerField(default=1)
    data = JSONField(default='{}')

The order field relates to a situation where there is more than one instance of the given diagram type on a page. The table for this model is read-only, so I am just doing simple GETs. Users only view one diagram instance at a time. A diagram is selected by type, page, and (where relevant) order. My initial url design was this:

example.org/api/diagrams/A/pages/1/order/2/

Although there is a plurality of diagrams, the diagrams param suggests a collection - but the diagrams don't 'contain' pages. Same with the pages param. Obviously order can only be singular. So perhaps:

example.org/api/diagrams/type=A/page=1/order=2/

Or perhaps just go with query params:

example.org/api/diagrams/?type=A&page=1&order=2

Personally I prefer path parameters, but the main complication of this is that the order param is actually redundant most of the time - there are only a small number of cases of repetition of a diagram on a page (currently I default order to '1', both on the backend and in the request). So perhaps a combination of both path and query parameters:

example.org/api/diagrams/A/page/1/?order=2

Is this a good pattern? Are there other alternatives I could consider?


Edit: After some additional reading (notably the URI Standard) I think the answer is that a path parameter design is suited for a hierarchical structure... which seems intuitive. But I don't have that, so the right candidate is the pure query parameter design. Right?

1 Answer 1

4

Could I suggest a different approach? I know, that may not be the answer you are looking for, but instead of trying to publish the exact object model from your code, think about what "kind" of resource the client needs to see and what is it related to.

For example if the client needs to "browse" the diagrams, you could have 2 media-types, one for listing all diagrams, and for a single diagram itself. The URIs could be:

/api/diagrams/          <-- list of all diagrams with titles
/api/diagrams/1         <-- a single diagram
/api/diagrams/2
...

If the client needs to browse per manual per page, then you can offer those too with additional media-types representing a manual (list of pages), and the pages with links to the diagrams that are on it. For example:

/api/manuals         <-- list of all manuals
/api/manuals/1       <-- list of pages, maybe a list of all diagrams in manual
/api/manuals/1/page2 <-- list of diagrams on page2

The same for your case about browsing per order and diagram type.

If you only need a "search" API, and not a "browse" API, then the proper solution would be to create a "form" in which you can submit the information (order, type, page, etc.). So that would be 2 media-types, one for the search description, and probably one for diagrams.

The point is, URI should not be fixed if you are trying to create a REST API. The server should provide the URIs to the client (except for the start URI, the search page for example).

This has several advantages, one being that you can control your URIs on the server. You don't have to be RESTful though, if you don't want to, but even then the URI itself does not really matter if you control the client anyway. Neither your approaches is wrong by objective measures.

Sorry if that does not help.:)

1
  • Thank you so much for your insights on this, they are very much appreciated.
    – ChrisM
    Commented Feb 23, 2016 at 14:59

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.