This commit is contained in:
Carson Gross 2023-01-29 08:27:57 -07:00
parent 4835b8c7bc
commit c585ec3f03

View File

@ -77,8 +77,8 @@ REST-ful architectural style places on the entire system.
In particular, the client needs to satisfy the [uniform interface](https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_1_5),
in which the client code knows nothing about the "shape" or details of the response beyond the ability to display
the given hypermedia to a user. In particular, the client isn't allowed to have "out of band" knowledge about the domain
that a particular hypermedia representation, er, represents.
the given hypermedia to a user. In a properly functioning REST-ful system, the client isn't allowed to have andy
"out of band" knowledge about the domain that a particular hypermedia representation, er, represents.
Let's look at the proposed JSON-as-hypermedia again:
@ -100,13 +100,28 @@ Let's look at the proposed JSON-as-hypermedia again:
}
}
```
A client of this API *could* simply and generically transform this JSON into, say, some HTML, via a client-side templating
language.
However, note that there isn't a lot of *presentation information* in the JSON response: it is just some raw data about
the account and then some URLs. A client that wanted to satisfy the uniform interface constraint of REST doesn't have
much information on how to present this data to a user and would, necessarily, need to adopt a very basic "name/value"
approach to displaying things. What else could it do?
Now, a client of this API *could* use a generic algorithm to transform this JSON into, for example, some HTML. It could
do so via a client-side templating language that, for example, iterated over all the properties of the JSON object.
But there's a hitch: note that there isn't a lot of *presentation information* in the JSON response. It is a fairly raw
data representation of the account in question, with a few additional URLs.
A client that wanted to satisfy the uniform interface constraint of REST doesn't have much information on how to present
this data to a user. The client would, therefore, need to adopt a very basic approach to displaying this account to an
end user.
It would probably end up being roughly a set of name/value pairs and a set generic of buttons or links for actions, right?
There simply isn't much more it could do while remaining agnostic about the form of the JSON response.
We could fix this by making our JSON API more elaborate and start including more information on how to lay out the
information: perhaps indications that some fields should be emphasized, or hidden or what have you. But that would only
be part of the story.
We would also need to update our client side to interpret these new elements of the API properly, so we are getting
in to the hypermedia *client* creation business as well. Or, more likely, we are asking our *API clients* to get into
the hypermedia client business as well.
Now, Mike Amundsen has written an [excellent book](https://www.oreilly.com/library/view/restful-web-clients/9781491921890/) on
how to build a proper, generic hypermedia client. But what you will see in that book is that creating a good hypermedia
@ -115,30 +130,40 @@ the JSON API had hypermedia-ish controls in their responses.
## Inefficient Representations: Good
As we begin to consider adding more information to our JSON response, a quote from Roy Fielding's dissertation jumps
to mind:
> The trade-off, though, is that a uniform interface degrades efficiency, since information is transferred in a
> standardized form rather than one which is specific to an application's needs.
_-Roy Fielding, <https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_1_5>_
A criticism of HTML is that it mixes "presentation" information with "semantic" information. But, it turns
out, it is exactly that presentation information, and the ability of the web browser (i.e. the hypermedia client) to
A criticism of HTML is that it mixes "presentation" information with "semantic" information. This is often contrasted
unfavorably with the brevity of typical JSON API responses.
It turns out, however, that it is exactly that presentation information, and the ability of a web browser (i.e. a hypermedia client) to
turn it into a UI that a human can interact with, that makes HTML work so well as a component of the larger hypermedia
system that is the web.
And that exactly what we find ourselves adding to our own JSON API to support a proper hypermedia client.
## Creating Hypermedia Clients: Hard
So just offering hypermedia controls in a JSON API response isn't enough. It is *part* of the REST story, but not the
entire story. And, I have come to understand, it is not really the *hard* part of the story. In fact, creating the
So, you can see, just offering hypermedia controls in a JSON API response isn't enough. It is *part* of the REST story,
but not the entire story. And, I have come to understand, it is not really the *hard* part of the story. In fact, creating the
hypermedia *client* is the hard part, and creating a *good* hypermedia client is *the really hard part*.
We are all used to web browsers just being there, but think for a moment about all the technology that goes in to simply
Now, we are all used to web browsers just being there, but think for a moment about all the technology that goes in to simply
parsing and rendering HTML to an end user in a normal, every day web request. It's *extremely* complicated.
That's why, if we want to build web-based [hypermedia-driven applications](https://htmx.org/essays/hypermedia-driven-applications/),
we should probably use the browser: it is already an extremely powerful and well tested hypermedia client, and,
[with a bit of help](https://htmx.org/docs), it can be an even better hypermedia client.
it's probably a good idea to use the standard, web-based hypermedia client: the browser.
Better for most engineers to build on top of an existing hypermedia client than to try to build their own!
It is already an extremely powerful, well tested hypermedia client. And, [with just a bit of help](https://htmx.org/docs),
it can be an even better hypermedia client.
In general, building a good hypermedia client that satisfies all the constraints of REST is hard, and we should leverage
(and extend) existing clients rather than building our own.
That being said, there are times when building a new hypermedia client is appropriate. For example, this is what makes
a technology like [Hyperview](https://hyperview.org/) so impressive and special. Hyperview
@ -163,15 +188,18 @@ API can be useful is if it is consumed by a proper hypermedia client. Otherwise
on what is, at the end of the day, a domain-specific thick client that just wants to get things done.
Further, your hypermedia API is almost certainly going to have to carry a fair amount of presentation-layer information
in it to make the whole thing usable. It turns out that "Level 3" of the Richard Maturity Model, Hypermedia Controls,
*isn't* enough. In practice, you are going to need to add in a bunch of practical presentation-level technology to make
your hypermedia API really work.
in it to make the whole thing usable. It turns out that "Level 3" of the
[Richard Maturity Model](https://martinfowler.com/articles/richardsonMaturityModel.html), Hypermedia Controls, *isn't*
enough to reach "The Glory of REST".
In practice, you are going to need to add in a bunch of practical presentation-level technology to make
your hypermedia API really work, *and* you are going to need a properly built hypermedia client to consume it.
I had a nascent sense of this when I wrote [HATEOAS Is For Humans](https://intercoolerjs.org/2016/05/08/hatoeas-is-for-humans.html),
but I didn't, at that time, appreciate just how special the browser was.
but I didn't, at that time, appreciate just how special the client/web browser was.
REST isn't just about APIs, and, except for a few people like [Mike](https://training.amundsen.com/), we've been largely
ignoring the larger (really, *much* larger) part of the REST story:
REST isn't solely about APIs. Except for a few people like [Mike](https://training.amundsen.com/), we've been largely
ignoring a larger (really, *much* larger) part of the REST story:
<div style="text-align:center;padding-top: 24px">