Live data from Hacker News

Problems with RESTful APIs (2015)

mmikowski.github.io

71–80 of 224 posts

Re: Problems with RESTful APIs (2015)

#71
I've never actually seen a REST API in practice, just HTTP APIs, by which I mean I've never seen a fully hypertext driven interaction with data. Let me sketch what I would expect that to look like.

I fetch from a URI (http://example.com/meep/boris) and get back a response with Content-Type application/meep; version=3. My browser searches for a viewer for that content type. The content type defines the actions I can take on the content, either locally or talking to the server, just as it does for any other protocol passing data over the wire. That understanding has to be out of band for the model.

But to be truly RESTful, the viewers must also be accessible via hypertext. For example, the response with the content could include a link header to point me to a usable default viewer for the content type. So you have to have a content type that whatever you're using (browser, SPA in the browser, etc.) knows how to interpret as a handler for content types. Whether it uses PUT, PATCH, or BABOON in HTTP verbs should be irrelevant. That's part of the protocol of the content type handler.

It's that second part that's a problem. The security implications are a bit worrisome. And if you're shipping handlers only for your own data, you control all the pieces, so there's no point going through all the decoupling.

Re: Problems with RESTful APIs (2015)

#72
Like other posters have said, the author appears to be pointing out shortcomings with HTTP, not REST. Roy Fielding made it fairly clear that REST is not strictly associated with HTTP. REST, as an architectural style, is defined by a set of constraints: https://en.wikipedia.org/wiki/Representational_state_transfe.... Anything that meets these constraints is considered "REST". Most of the constraints sound like common sense for API design, and where most APIs are disqualified from being truly "REST" and merely "RESTish" is in trying (or not) to fulfill the Uniform Interface/HATEOAS constraint: that the client dynamically traverses information and operations from one resource to another via hypermedia links.

Interestingly there's yet a deeper problem with fully RESTful APIs (Hypermedia APIs), where REST's Stateless Protocol constraint combined with HATEOAS creates an API where clients need to undergo multiple HTTP round trips to load the data they need. For example, suppose your app lets users browse movies. You might have a sequence like:

client: "hey, I'm gonna act like a browser and hit api.com and take it from there" GET api.com => { "movies": { "rel": "content/movies", "href": "/movies" } }

client: "hmm, ok I guess I'll click the movies link" GET api.com/movies => { "items": { "count": 4, "prev": null, "next": "/movies/page/2", [ {"href": "/movies/1"}, {"href": "/movies/2"}, {"href": "/movies/3"}, {"href": "/movies/4"}, ] } }

client: "ok, I guess I'll fetch each of those movies (I kinda wish the server had just told me what those contents were in the first place)" GET api.com/movies/1... etc. => { "href": "/movies/1", "rel": "self", "title": "Waterworld", "image": "/images/waterworld.png", } ...

And don't forget the client-side logic to join/order all this data and handle errors. This problem is called "underfetching" and it's present in true REST APIs by design. Ironically, many "RESTful" APIs break from the REST constraints specifically to avoid this problem.

Another great article on REST APIs: https://martinfowler.com/articles/richardsonMaturityModel.ht...

Re: Problems with RESTful APIs (2015)

#73
Sorry for the controversial question, and I probably raised my eyebrow if I saw a candidate choose XML over JSON when taking on a recent project... but really, why JSON? No comments, no multiline, no schema. I understand that XML is bad because ____ (not cool, verbose, old school, only enterprises use it?) I am not a huge YAML fan but it seems this is the only human readable form of JSON. The lack of self describing human readable scheme is mind bugling. So SOAP and XSD is bad (?) so instead we got swagger (?) is it really better?

Was ditching XML for JSON just due to cosmetic / trending reasons?

We still use HTML for markup. Why did everyone ditch XML for JSON beyond just treading reasons is an interesting question.

Re: Problems with RESTful APIs (2015)

#74
What is it about CRUD over HTTP that drives some people nuts? A bit too much overhead, not perfect for high performance/low level data channels, and not perfectly standardized. But it piggybacks over a wildly popular level 7 protocol that takes care of security in a well tested way, already plays well with proxies/load balancers, has thousands of implementations in most languages, is well understood by network admins and usually already handled if you're shipping software to customers. It has a lot going for it.

Sure - everybody ends up reimplementing async jobs and polling... some people prefer XML/json/edn/etc... some people get pedantic on 3xx and non-200 2xx status codes... differing standards on referencing other objects/collections/etc... some people use POST where they should use PUT (or insist upon using PATCH and OPTIONS). It has just as many faults.

But it's wildly successful for are reason, and dismissing it probably is going to result in relearning a bunch of hard-earned lessons about integrating across lots of very heterogeneous systems and environments.

Re: Problems with RESTful APIs (2015)

#75

I'm going to have to call bullshit on that one. REST is one of the more successful strategies we've come up with for connecting systems, this is just another case of letting perfect stand in the way of good enough. Using GET for non-destructive operations and POST for updates and deletes is a nice, portable compromise. I've been trying hard for years to find a reason to bother with PUT, but so far I've found it not w…

> I've been trying hard for years to find a reason to bother with PUT, but so far I've found it not worth the effort. And right there, at your final sentence, you basically described why REST has more or less failed. GET and POST are useless for implementing a complete application protocol. You'd basically overload these http verbs to the point where you would implement your own protocol. And that's what most people…

> "REST is nothing but loosely connected guidelines that nobody uses in the same manner"

But is that really a huge problem?

Look at more rigorous rpc standards with more rigorous standards and formal interface definitions: RMI, xmlrpc, CORBA, SOAP, Thrift, AMF... I'm sure there are loads and loads of real world systems using these and they have their place, but REST has succeeded in a large niche that they have not.

Re: Problems with RESTful APIs (2015)

#76
post #56

Earlier quoted context omitted.

> As the article points out, there are all too many HTTP libraries that only support GET and POST, not the more "esoteric" verbs like PUT and DELETE. GET and POST are all you really need for REST.

What we really need is a set of verbs that allow to reliably distinguish between these three types of operations: 1. Pure read. 2. Impure (stateful) read. 3. Idempotent write. 4. Any other write. There's no particular reason to separate inserts, updates, deletes etc as part of the protocol - they're all just different kinds of writes, and middleware doesn't derive any benefit from being able to distinguish them. Thus…

Why oh why oh why do you want a stateful read? That will be the beginning of the end for your architecture.

Re: Problems with RESTful APIs (2015)

#77
post #56

Earlier quoted context omitted.

What we really need is a set of verbs that allow to reliably distinguish between these three types of operations: 1. Pure read. 2. Impure (stateful) read. 3. Idempotent write. 4. Any other write. There's no particular reason to separate inserts, updates, deletes etc as part of the protocol - they're all just different kinds of writes, and middleware doesn't derive any benefit from being able to distinguish them. Thus…

Why oh why oh why do you want a stateful read? That will be the beginning of the end for your architecture.

Logging/analytics? Paywalls?

Re: Problems with RESTful APIs (2015)

#78
Agree totally. REST is hard to work with and very confusing since every application does it differently. I have seen applications returning HTML response for errors cases. REST is better than SOA or CORBA, but we need something better.

Re: Problems with RESTful APIs (2015)

#79
post #8

The "true spirit" of REST, to me, is that there's a certain set of things you can do when creating an API that will let you re-use the huge amount of HTTP middleware that's been written and get correct (and useful!) semantics from it. Caches (browser-, edge-, and server-side-), load balancers, forward- and reverse-proxies, application-layer firewalls, etc. will all "just work" for your software if you do REST correct…

The "true spirit" of REST, to me, is that there's a certain set of things you can do when creating an API that will let you re-use the huge amount of HTTP middleware that's been written and get correct (and useful!) semantics from it. Caches (browser-, edge-, and server-side-), load balancers, forward- and reverse-proxies, application-layer firewalls, etc. will all "just work" for your software if you do REST correct…

Or (for REST apis that might need concurrent updates of the same model) the most awesome "esoteric" verb, PATCH

Re: Problems with RESTful APIs (2015)

#80
This article is a complete strawman. His description of a supposed "REST"ful API is the least RESTful API I've seen in a while:

> The what-we-actually-indended-to-use request method embedded in the request payload, e.g. DELETE

Don't do this.

> The what-we-actually-indended-to-use response code embedded in the response payload, e.g. 206 Partial content.

Don't do this!

> If you’ve ever worked with a RESTful API, you know they are almost impossible to debug.

You're begging the question.

There exist plenty of APIs that abuse the HTTP methods and status codes, which I feel like is really the core argument being made. But completely ignoring it and what its purpose is is throwing the baby out with the bathwater. Read and understand the RFCs for HTTP, for a start; unfortunately, I'd wager that far too many devs of ostensibly RESTful APIs do not do this, and it shows when you get a response with a status code that makes zero sense. The vast majority of HTTP APIs I've interacted with violate both the semantic meaning of the methods and that of the status codes. (GitHub's is about the best I've ever seen.) A "RESTful HTTP API" is an API that uses the mechanisms in HTTP to accomplish the ideas of REST; (i.e., I'm not trying to equate HTTP and REST, I just think abuses of HTTP are a major impediment to understanding REST. Using HTTP well will naturally help you accomplish REST.)

> can anyone out there explained to me what 417 Expectation failed really means?

You've not read and understood the RFCs for HTTP. 417 Expectation Failed is obvious if you have; an expectation (on the request) failed (cannot be met by the server). An "expectation" is denoted on the request through use of the "Expect" header. The only existing expectation is 100-continue. Even if you do not know this by heart (and I don't expect that), it's readily findable:

1. Google "http rfc status codes"; unfortunately it's the second result; Google doesn't understand that the second result is an updated version of the first. Regardless, if you go for the first result, it points you to the second (-ish, b/c the RFC was split into multiple).

2. You select "417 Expectation Failed" in the Table of Contents.

3. You read the extremely straight-forward explanation. If you don't understand what the Expect header is for, the RFC links you to it.

So what are the ideas of REST? Start at its (de-)acronym: "Representational state transfer". That is, transfer of a resource. A "resource" is just an "object" or a concept, a thing — the actual concrete thing represented by a resource is going to be determined by your domain specific problem. E.g., "a user's profile data", "a message in a thread", "a news article" are all "resources" in that they embody some concept or idea that we want to communicate the underlying state of. You also need a standard, or uniform method of uniquely identifying, or locating these resources, which is what a URL is for (you then see why it's lit. uniform resource locator). So we build URLs to stand in as names for resources.

In order to transfer the state of a resource, embodied at a URL, you need to send it across a wire. You need to serialize it into some representation that's going to get transferred. That's what HTTP is supposed to help you do.

If you were writing a RESTful API, embedding things like the status of the operation in the response body should feel wrong, because the status isn't conceptually a part of the resource you were trying to operate on in the first place; go back to our example of "a post in a thread" — whats a status got to do with that? While technically, yes, HTTP's entity body is capable of transferring arbitrary binary data, the end result of using it that way results in simply the re-invention of wheels, such as needing to signal the success or failure of operations on resources. HTTP's purpose, alongside the ideas of REST, is to pull out the common bits that occur when writing code that transfers representation of stuff around, such as, e.g., caching, getting an ok to transfer large content prior to writing it all out to the wire, knowing the status of the operation, or pagination of collections of resources. (I cannot count the number of times I've witnessed API designers reinvent pagination, badly!)

The manner in which people like to use HTTP, with effectively only GET and POST (maybe!) is more akin to RPCs to me. It works. You can do that. But you then need to handle caching, pagination, status of operations, etc. on your own, and you'll end up, I believe, reinventing HTTP. Doing a lot of that (I think, and I think this was Roy's original point) is more effective if you structure your operations around transferring representations of resources around; this is especially visible in caching, because in caching you need the representation of a resource, because that's what a cache works with by its very nature. (As opposed to, say, making opaque method calls on a remote instance.)

Go read [1]; nothing really in there is bound to HTTP, just that HTTP makes a lot of it easier. Also, while I understand that Roy has a lot of arguments around how representations should be hypertext — and I agree with them, mostly — I think that comes second to the ideas that:

1. A URL represents a resource

2. The point of GET / PUT / DELETE is to transfer the state of that resource.

If you don't understand those two points, I don't think you'll understand the arguments behind hypertext.

[1]: http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch...

The other points,

> They are easy to debug since transaction information is found in easy-to-read JSON inside the payloads using a single, domain specific vocabulary.

Pushing everything into an opaque blob removes the ability for any tooling to pull out high level information. Chrome devtools, httpie, etc., all disprove this point.

> Problem #1: There is little agreement on what a RESTful API is

I agree. I also feel like too many people who think they know have not read anything from Roy Fielding, or even the HTTP RFCs.

> The REST vocabulary is not fully supported

depends mostly on

> most client and server applications don’t support all verbs or response codes for the HTTP protocol. For example, most web browsers have limited support for PUT or DELETE. And many server applications often don’t properly support these methods either.

This isn't true: JavaScript in all browsers in respectable use supports this; Android and iOS fully support HTTP; most server-side development languages have excellent tooling for this. This is a completely false statement, and requires proof, or at least a concrete example to back it up. (Were it true, it only invalidates the use of HTTP as an aid to accomplishing REST.)

> Problem #3: The REST vocabulary is not rich enough for APIs

POST is, essentially, a catch-all for odd operations not supported by other verbs.

> Imagine we create an application where we want to send a “render complete” response back to an HTTP client

If we have a resource that represents a rendering job, if you GET a representation of that render job, it can include some indication of completeness. The bigger problem here is actually HTTP's polling, IMO. Websockets might serve this specific example better, but this singular example doesn't invalidate that most web APIs boil down to CRUD $object of $type, which HTTP supports phenomenally well.

> Problem #5: RESTful APIs are usually tied to HTTP

Well, yes. At the end of the day, it has to be tied to something. HTTP is a pretty good something, with decent tooling.

> They use only one response code to confirm proper receipt of a message - typically 200 OK for HTTP.

Yes, you can send a single bit back. HTTP attempts to be a bit more rich than this. E.g., if something is in progress, and attempting to retrieve the data I just stored will fail until some serve-side job is complete, HTTP can easily signal this. Muxing them into 200 OK removes that information.

> They completely separate the response content from the transmission mechanism. All errors, warnings, and data are placed in the JSON response payload.

HTTP already has this: the response content is the body of the response. The transmission mechanism is HTTP. I don't want errors, warnings, etc., in the payload, where they are opaque and unusable by common tooling.

> They can easily be moved or shared between transmission channels such as HTTP/S, WebSockets, XMPP, telnet, SFTP, SCP, or SSH.

These channels do not support transferring the state of something. (Okay, HTTP does.) telnet is a mostly dumb pipe, same for SSH. You would need to build some custom, non-iteroperable layer on top of that. HTTP is the standardized version of that.

Post reply on HN