Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions text/019-api-hateoas.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# RFC 19:

* RFC: 19
* Author: Duco Dokter
* Status: Draft
* Created: 2018-03-14
* Last Modified: 2018-03-20

## Abstract

The current Wagtail API is limited in terms of resource coverage and
per-resource explicitness. Use cases for an extensive API range from a
full blown headless CMS to browsable objects for front-end selection
of, for example, pages, images and documents. Even though full
coverage may not be in the scope of development for now, the API needs
to be set up in a way that enables consumers to extract information in
a uniform way and that allows for future extension.


## Specification

The Wagtail API is implemented with the de facto REST implementation
of _django\_restframework_, or _DRF_. This framework however doesn't
provide the level of explicitness that is needed for a REST
implementation that is truly RESTful in terms of the original concepts
as defined by Roy Fielding. The fourth guiding constraint states,
among other things:

... hypermedia as the engine of application state.

or in other words: the state of the resource should be reflected in
it's representation. This phrase is usually shortened to
HATEOAS. Indeed, not all acronyms make things easier.

A typical example in the context of a CMS would be the representation
of a page. Let us assume that a page can either be public, or private,
and that a consumer with the proper authorisation can change this
state. A representation of the page would then not only need to show
Comment on lines +35 to +38
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to demonstrate the relevance of HATEOAS in the context of Wagtail I think we should do this without relying on authorization or "write API" use cases. This isn’t a typical example, there are sites that do this but most of the CMS-driven content shared over an API I see out there seems to be read-only. There might be some form of authentication but I’ve not seen much in the space of authorisation at all.

See the 2024 headless survey, where the "admin API" improvements are ranked lowest as far as priority for Wagtail users.

the state, but also the way to change it. HATEOAS does not dictate
*how* to achieve this. However, usually implementations use some kind
of meta information on a resource. So, this would be a resource representation
lacking in hypermedia:

{
'id': 666,
'title': 'Designing great beers',
'author': 'Bob Dobalina',
'state': private'
}

and this would be the HATEOAS version:

{
'id': 666,
'title': 'Designing great beers',
'author': 'Bob Dobalina',
'state': private',
'_links': {
'self': 'http://be.er/api/pages/666/',
'publish': 'http://be.er/api/pages/666/publish/'
}
}

and this would be the same page, for a consumer without proper
authorisation for publishing (but enough to see private pages...):

{
'id': 666,
'title': 'Designing great beers',
'author': 'Bob Dobalina',
'state': private',
'_links': {
'self': 'http://be.er/api/pages/666/',
}
}

After publication, the page to the authorised consumer, would look like this:

{
'id': 666,
'title': 'Designing great beers',
'author': 'Bob Dobalina',
'state': public',
'_links': {
'self': 'http://be.er/api/pages/666/',
'unpublish': 'http://be.er/api/pages/666/unpublish/'
}
}

So: if the consumer can perform any kind of action other than the
standard CRUD methods for REST, it should be reflected in the
resource. This allows any consumer, be it human or robot, to navigate
through the API and to detect what actions may be performed on a given
resource. A page edit screen using the REST resource for example,
would show the 'publish' button only if the link is available.

This proposal consists of the following:

1. implement a root view for the API, where all available resources
are listed, so a consumer can start navigation from here;
Comment on lines +99 to +100
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See Wagtail API should have a browsable root URL #1921. Neat idea. I think the RFC should refer to this.

2. implement HATEOAS for all resources using the *_links* meta property;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be expanded. To me that’s what would be most interesting to cover in RFC format, going beyond why HATEOAS is interesting.

3. provide documentation for all views for human consumption on filtering
or search options for the given resource.

This way, a consumer always only needs to know one URL, being the root
URL for the API. All further navigation is provided.


## Sometimes a working demo says more than a thousend words

... and usually is much less work to write. So you may want to check
out wagtail.campsix from Github, install it, andsee what I mean:

https://github.com/ddokter/wagtail.campsix


## Open Questions