ADR 3: Resource-oriented, hierarchical API
==========================================
Context
-------
The problem
~~~~~~~~~~~
We don't currently have any explicitly agreed conventions or patterns for how we
structure our API. As different parts of our API are implemented in different
ways, people looking to integrate with our API are having a harder time than
necessary learning how it works.
The lack of agreed conventions also slows us down when designing new
functionality, as we don't have a standard set of patterns to draw from.
Extra context
~~~~~~~~~~~~~
The part of our API that deals with creating, retrieving and modifying
annotations is currently resource-based, with ``GET``, ``POST``, ``PATCH`` and
``DELETE`` requests to suitable URLs. This is also the style used in the W3C
`Web Annotation Protocol`_.
.. _Web Annotation Protocol: https://www.w3.org/TR/annotation-protocol/
Some examples of other APIs that could provide inspiration:
- The `GitHub API `_ (resource-based,
hierarchical style)
- The `Slack Web API `_ (RPC style)
Decision
--------
We're going to build our API in a resource-oriented, broadly RESTful style (with
standard HTTP verbs operating on resources at URLs).
We'll nest resources liberally. For instance, when flagging an annotation for a
moderator's attention, we would use a ``PUT`` request to a sub-resource of the
annotation::
PUT /api/annotations//flag
Content-Type: application/json
{"reason": "spam"}
One advantage of this method is that parameters can often be made mandatory by
construction: in the example above, it becomes impossible to flag an annotation
without providing the annotation ID. This is similar to the approach GitHub
takes for `locking issues`_.
.. _locking issues: https://developer.github.com/v3/issues/#lock-an-issue
The operation to remove such a flag would then be expressed with a ``DELETE``
request to the same URL::
DELETE /api/annotations//flag
An example of a pattern we are *not* choosing to follow is to post these flags
as top-level entities::
POST /api/flags
Content-Type: application/json
{"annotation": ""}
While this is a reasonable approach to take, we think that the more hierarchical
approach will make the relationships between different entities (in this case,
annotations and their associated flags) easier to understand.
Status
------
Accepted.
Consequences
------------
With a set of default patterns for how we implement new functionality (or
restructure existing functionality), this should result in a more consistent API
and an easier time for those trying to integrate with our systems.
Another benefit should be that this speeds up development, by giving us a base
set of patterns from which to design new functionality. This should also make it
easier for reviewers, as they can more confidently review a proposal if it
follows these conventions, or look for more context if it doesn't.