3 ms·
I will bet money that most of these "RESTful" APIs are nothing of the sort. In almost all cases, when somebody says they're using REST, they're actually using a
by jmillikin 16y ago
I will bet money that most of these "RESTful" APIs are nothing of the sort. In almost all cases, when somebody says they're using REST, they're actually using ad-hoc XML-RPC -- fixed URLs, non-descriptive content, etc. Ignorant programmers have fixated on trivial aspects of some REST applications (use of PUT/DELETE, "pretty" URLs) and ignored all the important aspects.
This sort of thing happens a lot in software culture -- see people claiming Java or C# are object-oriented, that C++ is functional, that Python or LISP are "scripting languages". It's cargo-cult nomenclature, and it disrupts technical conversation to the point of uselessness.
Roy T. Fielding, who described the REST style, has an excellent blog post titled REST APIs must be hypertext-driven < http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hyperte... >, where he lays out some ground rules for calling any given interface a REST API.
- tptacek 16y agoI find Fielding's writing on REST opaque to the point of unintelligibility. This is a prime example. He actually has an example of a HTTP/XML interface he doesn't like... but he can't bring himself to talk in specifics, and instead hews to academic jargon. So, can you translate his bullet points for me? Or can I safely assume that, yes, Roy Fielding doesn't believe these interfaces are "REST", but that I can safely ignore that fact and use the term "REST" the way the rest of the world does (RPC that uses URL patterns instead of WSDL).
- jmillikin 16y ago------------ 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. A REST API should work over any protocol (HTTP, FTP, SSH, whatever) with enough basic functionality to support it. It shouldn't mandate any particular protocol. ------------ A REST API should not contain any changes to the communication protocols aside from filling-out or fixing the details of underspecified bits of standard protocols A REST API shouldn't require a customized version of the underlying protocol. ------------ 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 Here's big idea #1. Documentation for a correctly designed REST API will describe mostly what is being returned, not how to get it. Each resource is accessed via a different resource, except for the standalone root. For example, you might start at the root resource http://foo.com/api/ http://foo.com/api/ . It returns, as content, a set of subresources that can be requested. The API documentation should describe what data the server sends for /api/ -- what format it's in (HTML, XML, JSON, etc), how to find its subresources (<a>, <form>, id'ed elements), and any relationship metadata it contains. The user agent (web browser) uses the MIME-type returned by the server to parse whatever it returns. ------------ 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. Big idea #2: the API documentation shouldn't just be a list of URLs; if it is, the server's URLs can't be modified without breaking clients. Clients should use hypertext to parse URLs retrieved from the server. For example, the front page doesn't just give you a list of story IDs and require you to build the URL manually. It provides each URL in an anchor, as an opaque identifier, and your web browser simply passed it back to the server to get whatever it points to. ------------ A REST API should never have “typed” resources that are significant to the client. Specification authors may use resource types for describing server implementation behind the interface, but those types must be irrelevant and invisible to the client. The only types that are significant to a client are the current representation’s media type and standardized relation names. The client shouldn't have to contain a list of what URLs return what data. If http://foo.com/students/ http://foo.com/students/ returns a student list, either use the MIME-type (application/x-foo.com-students) or a standardized relation name (<foo.com><list rel="students">...). For XML-based APIs, I would encourage the use of XML namespaces, although Fielding doesn't mention them. Sometimes you've got a few dozen different document types, and it just isn't worth figuring out MIME-types for them all; in that case, return (application/xml) and let the client use the namespace'd root element as an identifier. ------------ A REST API should be entered with no prior knowledge beyond the initial URI (bookmark) and set of standardized media types that are appropriate for the intended audience This is mostly an elaboration of previous bullet points; clients shouldn't have to hardcode a list of resource locations. If your client has something like "students = Resource("/students/"), it's going to break when the server changes that URL.
- tptacek 16y agoThanks. You should make a blog post out of this; call it the "Fielding Decoder Ring" or something.
- kaitnieks 16y agoThe biggest problem I see with this is that in real life clients will hard-code the urls anyway and break when the urls get changed.
- beza1e1 16y agoWhy is this the biggest problem? For every protocol there are broken clients. For example, most XML parsers are broken. That is not a problem of XML, is it?
- glhaynes 16y agoWhat's the alternative? For clients to refresh their copy of the "parent" resource [there may be a better term for this... I mean the resource used to access the resource that is to be gotten] often? For a commonly interactively accessed thing, it would introduce a lot of latency for clients to get it every time, so I suppose it must be cached... and then the cache of the parent resource be refreshed regularly and in case of failure? How far up the tree should that go? In other words, if I want to get the Twitter feed for Joe's "ABC" group and I don't want to hardcode the URL for that resource, how often should I download (and cache), parse, and traverse the resources for Twitter's users then Joe's feed then Joe's ABC group, etc.? Or am I misunderstanding this?
- chrisbolt 16y agoIn this case respecting HTTP's Expires: or Cache-Control: max-age= headers seems like the thing to do.
- gryan 16y ago"For example, you might start at the root resource http://foo.com/api/ http://foo.com/api/ . It returns, as content, a set of subresources that can be requested. The API documentation should describe what data the server sends for /api/ -- what format it's in (HTML, XML, JSON, etc), how to find its subresources (<a>, <form>, id'ed elements), and any relationship" Good luck doing that for "FTP, SSH, whatever"
- barrkel 16y agoIt's really simple: consider documents retrieved by requests to be nodes in a state machine, and consider hyperlinks in the documents to be directed edges to other nodes. That's it: your state is your position in the state machine, and your state transitions are navigation through the web of hyperlinks. If you have an API which talks about URI patterns, for example, then it's not REST in this sense, because these URI patterns aren't found inside the documents as hyperlinks. Instead, they're found outside the document. Similarly, if state is not encoded and transformed by following links in the web of documents, and instead is implicitly understood to be occurring whenever you do e.g. a PUT of some URI pattern, then hypermedia isn't the engine of application state. A purist approach to REST, though, is IMO impractical for systems that aren't very like the web itself.
- DougWebb 16y agoA REST API should not be dependent on any single communication protocol... URIs don't have to start with http, and they don't have to be locators. The rest of his bullet basically says that if you use a non-locator identifier like urn:..., then some other metadata or method will be needed to allow the client to locate the named resource. For example, you might have a resource that can map isbn numbers to online reviews of a book. You can pass in a urn:isbn:### identifier as part of the request url and you'll get back a resource with one or more URLs that point to reviews. A REST API should not contain any changes to the communication protocols... Here he's saying that you shouldn't make up new methods. A RESTful API doesn't just use uniform resource identifiers, it uses uniform methods as well. The exceptions are to fill in gaps in the standard methods (which presumably would be fixed in future versions of the protocol standard) and to fill in gaps in implementations (like browsers not supporting DELETE.) The former should be part of the core definition of your API, but the latter should be in an appendix that describes a temporary workaround. A common approach is to allow POST with a parameter named _method to workaround methods that browsers don't support. 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.... Again, the methods are uniform and don't need to be described by the API. The media types and representations are resource-specific, so that's what the API documentation needs to focus on. A REST API must not define fixed resource names or hierarchies... Clients should never need to construct a url. Instead, every resource that the API can return should be reachable through a url that is embedded in another resource. All the client should need is the API's entry point. A classic example is a website: every page should be reachable through the home page by following links and submitting forms. You never need to go and edit the url directly to reach a given page. Browsers and protocol standards are lacking in this respect, because they don't yet support templatized URLs. The workaround here is to provide a url template and some metadata that tells the client how to fill in the template, and if your client is a browser perhaps some javascript that fill in the template appropriately. A REST API should never have “typed” resources that are significant to the client.... Unlike SOAP, which has typed data similar to a programming language (int, byte, string, boolean, etc) the only types in RESTful APIs are media types. The client is expected to know how to handle a media type in a useful and standardized way. This is related to the earlier point about the API documentation spending time defining the media types used by the API and how to interpret and use them (for non-standard media types.) For those who want data types, text/json is a good media type choice because it uses the typical programming data types. But if you use JSON you're going to strongly couple clients to your service because you can't modify the json response without modifying the clients that parse the response. If you control both sides that's not a problem, but if you don't or you need to update both sides independently a less-coupled and more metadata-driven representation would be better. A REST API should be entered with no prior knowledge beyond the initial URI (bookmark) and set of standardized media types that are appropriate for the intended audience (i.e., expected to be understood by any client that might use the API)... This bullet repeats what I mentioned above about clients not constructing URIs.
- rue 16y ago> I find Fielding's writing on REST opaque to the point of unintelligibility. I agree, somewhat, but I would formulate it a bit differently: REST is defined from a user's (or client's) standpoint. It is ill-defined on the other side, even to the point that it is hard to say whether any ruleset can be derived for implementers to use in building their applications. Essentially all of the popular conventions like Resource objects are somewhat misguided, as they are not in any way implied. I have tried to hammer it in to my acquaintances and colleagues that if you pick one thing about REST to base everything on, it is links, not URLs. I have pondered on writing a "everything you know about REST is wrong"-article, but have thus far been counterweighed by the consideration that perhaps this perversion that passes for REST is actually better than the real thing.
- jsdalton 16y agoI think you're wrong to dismiss most developers' efforts at a REST API as cargo-culting. A half-ass REST API is better than XML-RPC or SOAP, at least in my humble opinion. Out of curiosity, though, do you know of any examples of what you consider "true" REST APIs vs. examples of "ad-hoc XML-RPC masquerading as REST" APIs? Maybe I don't have enough experience consuming true REST APIs to be able to fully appreciate their merits.
- jmillikin 16y agoThe prototypical example of a REST API is a web application. They use a standard content type (HTML or XHTML), hypertext to link resources, and typically don't require any out-of-band technical information to work.
- jsdalton 16y agoRight, that makes sense. But I guess I don't really understand how that moves the conversation forward. Maybe I misread your original comment, but it sounded to me like you were claiming that there are a whole buncha crappy REST APIs out there that are no better than the crappy XML-RPC/SOAP APIs of yore, and that there would be a whole new world of coolness if only they stayed true to the REST protocol. Saying, "oh, it's just the web," is just another variation of the obscurity in Fielding's post that tptacek is complaining about in his comment. Anyhow, it's not like you have some responsibility to justify REST to me or anything, but I'm as yet unconvinced of what this gap between "true" and "pretend" REST APIs really is, and what benefits lie for everyone in close that gap. EDIT: Just saw your "translation" of that Fielding post in reply to tptacek's comment, which was quite helpful.
- jmillikin 16y agoI'm not claiming that XML-RPC or SOAP is "crappy"; there might be poorly-designed implementations (and of REST also!), but both have vital and important use cases. I have never used SOAP, but have both designed and consumed many XML-RPC APIs, and have no problem with them. It's very important to use accurate terminology when discussing software and technology. The statement "Foo.com uses a REST API" only contains useful information if 'REST' is meaningfully defined. If 'REST' is redefined as a synonym for 'XML-RPC', then we lose the ability to distinguish between a REST and XML-RPC API in written or spoken conversation. I am not making any value judgment regarding either API style; they are simply different, and should be kept distinct for the purposes of communication.
- masklinn 16y ago> Ignorant programmers have fixated on trivial aspects of some REST applications […] "pretty" URLs Hell, legible urls isn't even remotely part of REST, it's completely unrelated, it's absolutely possible to have a RESTful API with entirely unreadable URLs.
- heresy 16y agoThe problem is that he leaves so much underspecified. This may be a reaction to the extremes of WSDL and SOAP, but how could the current outcomes and state of "REST" APIs be any different, if no one person can agree particularly much on what a REST architecture is?