Hacker News new | past | comments | ask | show | jobs | submit login

This is an oft revisited topic, and it might be worthwhile to cite a few paragraphs from Dr Fielding in order to support and expand upon the submitted article.

"Search my dissertation and you won’t find any mention of CRUD or POST." [0]

> For example, some APIs may need to support actions such as submit, approve, and decline. With our somewhat limited action verbs in HTTP, how can we add this to our API?

By representing the difference in states. Or otherwise. The communication medium is not the API. ("A REST API should not be dependent on any single communication protocol, though its successful mapping to a given protocol may be dependent on the availability of metadata, choice of methods, etc. " [1])

> POST /articles/{articleId}/publish , POST /articles/{articleId}/submit , ... etc.

A few years ago I was zealously advocating against representing actions in URIs, and using a generic /actions [sub]resource, but this actually makes it simpler to represent the available actions to the client. And sure, this can be thought of as REST via the code-on-demand part of the architecture. The server points to a script (it doesn't have to be JS, but the media type must be defined in the REST API), that can understand the available actions from the state representation, and construct the necessary representations for the desired actions. (So in a HTTP API, the JS interprets the JSON and knows how to put together POST requests to modify the resources, without the actions having been reified and URI-fied in the JSON.)

> The workflow our API supports is more explicit, [...]

Sure, that's pragmatic, but after much gnashing of teeth and scratching of heads, REST is about presenting options to the client by offering various media types (content-types), and letting the client request the best representation, and not really about a fixed ACL neither about fixed flow.

From [1] again: "A REST API should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and driving application state, or in defining extended relation names and/or hypertext-enabled mark-up for existing standard media types. Any effort spent describing what methods to use on what URIs of interest should be entirely defined within the scope of the processing rules for a media type (and, in most cases, already defined by existing media types). [Failure here implies that out-of-band information is driving interaction instead of hypertext.]"

[0] https://roy.gbiv.com/untangled/2009/it-is-okay-to-use-post

[1] https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypert...




> "A REST API should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and driving application state, or in defining extended relation names and/or hypertext-enabled mark-up for existing standard media types. Any effort spent describing what methods to use on what URIs of interest should be entirely defined within the scope of the processing rules for a media type (and, in most cases, already defined by existing media types).

Arguably this is the problem: what Fielding is describing here has a well-known name: Object Oriented Analysis and Design. It's not at all clear why a new formalization was needed when we already have Objects. Resources have URIs, Objects have memory addresses. Resources have representations that are defined by content media types, Objects have behavior that are defined by -- types.

> POST /articles/{articleId}/publish , POST /articles/{articleId}/submit , ... etc.

Good ol' OOAD can avoid nonsense like this. It's immediately clear that the Resources identified by these URIs aren't real objects. If you want to talk Published Articles vs Submitted Articles you would introduce new types and new repositories.

The only way this makes any sense is:

POST /articles/published/ POST /articles/submitted/

Only now does 'GET /articles/published/{articleID}' make sense and we might think about what that content media type looks like vs submitted articles.


It looks like this is a case of the stereotypical academization. Fielding looked at the Web, and abstracted it, and calls it REST Architecture.

And of course, the problem is that nobody sits down to just do a quick World Wide Web API for an app, or an internal corporate business-as-usual thingie. In fact since the original hypertext project at CERN no one every did it. We still use the same Web, incrementally transformed into what it is today, but still the same HTML, same Content-Types, and HTML1.0-like markup. All eaten and excreted by JavaScript of course, but that's a prime example of something incremental, and not exactly thought out.

Moreover, there's not much to say about media types driving interaction, because 99.9% of the Web is GET GET GET. And OPTIONS (due CORS) is driven by out-of-band conventions (defined in the Fetch and the amended XHR APIs, but not much to do with media types - but of course, CORS is more about fixing the leaky encapsulations of the communications interface/layer, not about the content [the high level state being transferred]).


> Fielding looked at the Web, and abstracted it, and calls it REST Architecture.

yeah the perfect rest protocol is the web and the perfect rest clients are the humans that navigate the action represented on the hypermedia.

that said, there's some value to be had in discoverability, even if rest grossly gloss over how to discover parameters for the action that the state holds.


> that said, there's some value to be had in discoverability, even if rest grossly gloss over how to discover parameters for the action that the state holds.

There absolutely is and API systems like graphql have taken that to heart (playing with a graphql explorer is delightful).

But forcing all programmatic interactions through a "discoverability" layer is not useful, yet that's essentially what REST (as originally formalised) mandates.


I'm pretty sure that if I call `POST /articles/{articleId}/publish`, it will publish the article with ID `{articleId}`. Whereas I'm not sure how `/articles/published/` works.


That's actually a REST feature. You have to interact with /articles/published to get its media type and then based on that you will know what you can do with it. The URI shouldn't matter. It could be /4234234/224234324/020121020/xxxxAAAAzzz but if the media type is "published articles" which is defined in the API spec, then you will know what to do with it.


>>how can we add this to our API?

>By representing the difference in states.

Maybe I'm misinterpreting something here, but doesn't this directly contradict the following?

"A REST API must not define fixed resource names or hierarchies (an obvious coupling of client and server). Servers must have the freedom to control their own namespace. Instead, allow servers to instruct clients on how to construct appropriate URIs, such as is done in HTML forms and URI templates, by defining those instructions within media types and link relations. [Failure here implies that clients are assuming a resource structure due to out-of band information, such as a domain-specific standard, which is the data-oriented equivalent to RPC’s functional coupling]."

How do you implement the above without making out-of-band assumptions about the name/structure of each action state (e.g. /publish, /submit)? The server-provided links won't help you there, since they might as well be called /foo and /bar - after all, the server provides them and the client shouldn't have any prior knowledge about them.

I mean, sure you would associate each action state (/publish, /submit) with a media type, but that's just shifting the assumptions elsewhere, isn't it?


> advocating against representing actions in URIs

That is a lot of thinking for something that matters very little in REST. URI for actions are embedded in the response itself anyway. If you aren't using the actions as provided by the response, you're not doing REST.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: