11 ms·
How RESTful is Your API?
- bmunro 14y agoOff topic, but the right side of the paragraph is cut off on Android.
- housecor 14y agoThanks, fixed.
- rickmode 14y agoThe web page is unreadable on my iPhone. Right side is clipped; same as another post says about Android.
- njharman 14y agoThe accept header seems natural place for versions. oh and tacks not tax http://en.wikipedia.org/wiki/Brass_Tacks http://en.wikipedia.org/wiki/Brass_Tacks
- cwp 14y agoInteresting. He gives three examples of truly RESTful APIs, and Tim Bray was involved in creating two of them.
- davedx 14y agoDramatic, and makes broad unsubstantiated claims about API's "in the wild", but the details are right. His most important point that we as API writers can work on is the "discovery" part. Hardly anyone is doing HATEOAS [1]. I think the reason for this is that if you write a public API, you're going to document it well (or nobody will use it), and good documentation kind of alleviates the need for in-service discovery. [1] http://en.wikipedia.org/wiki/HATEOAS http://en.wikipedia.org/wiki/HATEOAS
- csulok 14y agoIn service discovery is just convenient. With SOAP libraries, using a web service is as easy as 2-3 lines of code. The library handles loading the wsdl file, generating functions with appropriate parameters, sending requests and parsing response and exception handling. Without this ability, it's a lot more code. It's not necessarily harder, but it's more code nevertheless.
- davedx 14y agoTrue. Once you have the right libraries in place working with SOAP can be surprisingly easy. I always find defining and passing data types/structures the most frustrating exercise with SOAP though, especially collections. REST makes that stuff so much easier.
- gizzlon 14y agoThe problem with SOAP + WDSL was just that it was overly complex and, in my experience, never worked cross-platform & cross-language. And since it was so complex it was "¤%& impossible to debug at lower levels. Argh! I hate soap with such a vengeance it's actually embarrassing.
- coopernurse 14y agoAgreed. These problems (complex tooling, poor interop, non-human readable WSDL) were my motivation for writing Barrister RPC (a JSON-RPC implementation with a human readable IDL). For those who find value in separating interface from implementation, you might take a gander. http://barrister.bitmechanic.com/ http://barrister.bitmechanic.com/
- deleted 14y ago[deleted]
- lmm 14y agoI still don't see the value proposition for HATEOAS. Writing a client that can use an API that it doesn't understand seems impossible, so I can't see how discovery is ever going to work. To my mind HATEOAS represents the very complex over-engineering that REST was originally a reaction against.
- lucisferre 14y agoThis is an excellent and insightful overview of REST both the good and the bad. It's the Hypermedia API problems that stand out the most to me here. It's definitely the unicorn of the whole thing.
- pbreit 14y agoI found the cheat sheet annoying. Doing all requests over GET is not acceptable, especially deletes. The jury is still out on GET/POST vs GET/POST/PUT/DELETE. I don't see any problem with file extensions. After all, that's how the web has worked from the very beginning. Hard to do discovery without any guidance on format. Version numbers are not very RESTful and I don't care for them. Spend a little extra design energy to avoid the need for versioning. Static URLs are sort of necessary absent better discovery mechanisms. He skips the notion of returning a resource address as a "Location" upon creation.
- jcdavis 14y agoAnnoying or not, its a fairly accurate description of the state of APIs. I agree about the all GET setup, although I've never actually seen that in the wild (seems pretty dangerous). I personally have no problem with using POST for all endpoints with side effects, though opinions certainly differ there.
- davedx 14y agoBecause a URL defines one resource in REST, so strictly speaking, /path/resource.json and /path/resource.xml are different resources using REST. Content-negotiation is what people should use to specify format.
- housecor 14y agopbreit - Point taken on using only GET. I have edited the article accordingly.
- chime 14y agoI've written probably half a dozen unrelated apps that call REST APIs and I think they all implemented REST differently. Some treat PUT as insert while POST as update. Some treat POST as insert, PUT as insert/update. Some return 201 when insert was successful, some return 200 whenever anything is successful. Some issue tokens, some authenticate using headers. Just last night I wrote some code to auto-create Trello cards and assign them to a specific list. The https://trello.com/docs/ https://trello.com/docs/ seem fairly decent but what they don't tell you is that POST is insert, PUT is update. Moreover, while you can assign a due date via PUT ( https://trello.com/docs/api/card/index.html#put-1-cards-card-id-or-shortlink https://trello.com/docs/api/card/index.html#put-1-cards-card... ), you cannot assign one via POST ( https://trello.com/docs/api/card/index.html#post-1-cards https://trello.com/docs/api/card/index.html#post-1-cards ). So if you want to create a card with a due date, you have to POST, read ID, then PUT the due date to /card/id. The problem with people trying to be RESTful is that they pay too much attention to stuff that doesn't matter (71 status codes) instead of stuff that really matters (simplify complex insert/update). I'd rather have Trello return 400 on errors and provide a text description than use one of the 30+ 4xx errors. And I'd rather have them accept due date when inserting a card. Trying to conform to REST's standards is like trying to be XHTML compliant. Great, your site validates. But you're still using white font on yellow background! Be as RESTful as you need to be. But more than that, be useful and sensible. Don't make me call your server six times to make one valid GET request.
- alexchamberlain 14y ago"POST is insert - PUT is update" is the norm and HTTP compliant way of doing things. Why not reach out to Trello and ask why you can't do the due-date on POST?
- arethuza 14y agoUnfortunately, I don't think the POST vs. PUT distinction is quite that simple - PUT is often used to create/insert if you are sending all the data required to create the new object as part of the request. NB Personally I thought this use of PUT was splitting hairs when I first started reading about RESTful interfaces but having used a few and written one RESTful service it does rather make sense.
- jakejake 14y agoI spent decent amount of time and effort making my code generator/framework create a proper RESTful API, but I have to admit it is a bit tricky to figure out what is actually "proper." I feel like I was able to do a decent job with everything except the discovery service. If any PHP devs would like to contribute or just look at the API please feel free at phreeze.com
- andrewdotnich 14y agos/tenant/tenet/g
- idan 14y agoThis.
- peterwwillis 14y ago...is not Reddit. Stop that.
- housecor 14y agoYep. Fixed.
- ljd 14y agoThere is much ado in the REST world about whether one API is more restful than another. For us, our REST API was designed from our experience as consumers of other REST API's. Our whole philosophy wasn't about what was true-rest but rather, what was both consistent and easy to learn. We do fancy stuff like send back HTTP codes that aren't always invited to the cool HTTP code parties like, "Payment Required" and we used "Accepted" on a PUT (Update). Also, while we know that a rest API should be entirely self documenting we found it more practical to create a GitHub account explaining every call with sample code in variety of languages, all doing the same thing: sending JSON via a REST library. We are a B2B product and reducing any barriers to enriching our clients is a must. We've worked on big dev teams and understand that if we want our product to get on the next sprint we need to make sure that they can copy and paste our code into their software and it'll work. It's just the nuts and bolts of business. I would accept data on floppy disk duct taped to carrier pigeons if that was the easiest way for clients to interact with our algorithms. Fortunately for us, being "pretty" rest-y was a better fit for everyone.
- regularfry 14y agoI'm surprised nobody has mentioned the Richardson Maturity Model: http://martinfowler.com/articles/richardsonMaturityModel.html http://martinfowler.com/articles/richardsonMaturityModel.htm.... It's explicitly for discussing and characterising the degree of RESTfulness of a given API. For my money there's nothing actually wrong with implementing, say, a level 1 API, as long as you don't claim anything higher. It'd be very nice for everyone to be at level 3, but obviously the tooling isn't there yet to support it universally.
- regularfry 14y agoHaving spent a while now working on a project with a RESTish API, I can say that I'm really regretting not pushing harder for hypermedia controls earlier. It would have made pushing upgrades out a lot simpler.
- shimonamit 14y agoEasier for you, that is. The problem with HATEOAS is that it requires commitment on both parties (server and client) to that convention. For the client developer that means no hard coding changing URLs. But they will, and you'll be to blame when your server changes break their code. You'll say "but you didn't HATEOAS" and they'll say "my app is broken, fix your API now" and you... who wants to go there?
- regularfry 14y agoIn this case we're in control of the server and the client, so it's less of an issue, but in general it's not the ability to change URLs that I'm getting at here, and that's not a flexibility we've needed. It's the ability to add extra functionality by adding links on each resource without breaking existing clients that I'm missing at the moment.
- shimonamit 14y agoAdding HATEOAS resource links should not break client code. It is nothing more than adding an attribute or sub-element to your xml.
- regularfry 14y agoPrecisely.
- deleted 14y ago[deleted]
- deno 14y ago> Notice what this doesn’t include? XML and JSON. Neither offers a native way to convey a hyperlink. Both XML and JSON offer standard ways to include hyperlinks. XLink[1] and JSON Schema[2], respectively. Not to mention you can include hyperlinks in headers[3]. The problem with “hypermedia” is that the concept is completely useless without common nouns and verbs. So it’s fine if you can fit your application to use WebDav or AtomPub plus extensions, but for a custom API there’s no point. [1] https://en.wikipedia.org/wiki/XLink https://en.wikipedia.org/wiki/XLink [2] http://json-schema.org/ http://json-schema.org/ [3] urn:ietf:rfc:2068 (https://tools.ietf.org/html/rfc2068#section-19.6.2.4 https://tools.ietf.org/html/rfc2068#section-19.6.2.4)
- deleted 14y ago[deleted]
- Natsu 14y ago> Why Deviate? > Although REST prescribes using HTTP GET, PUT, POST, and DELETE verbs for CRUD operations, some clients can’t generate the less common PUT and DELETE requests. In addition, some overzealous firewalls block PUT and POST. Thus, some RESTful APIs accept all requests via HTTP GET and place the HTTP verb in the querystring. For example, to delete user 124, the GET request would be for the following URI: /users/124?method=delete This technique is especially common in Ruby circles. Another benefit of this approach is all requests can be easily generated and manipulated in the address line of any browser. This is a very bad idea for something like delete. It's Daily WTF material: http://thedailywtf.com/Articles/The_Spider_of_Doom.aspx http://thedailywtf.com/Articles/The_Spider_of_Doom.aspx Any firewall that blocks POST requests but not GET is a WTF in and of itself, for that matter.
- tomchristie 14y agoOverloading the request method using URL paramaters, as the author mentions is a bad idea. What is accepted behavior, is overloading the request method using hidden form data in a POST request. The later is what Rails actually does - http://guides.rubyonrails.org/form_helpers.html http://guides.rubyonrails.org/form_helpers.html section 2.4 "There are two noncontroversial uses for overloaded POST. The first is to simulate HTTP's uniform interface for clients like web browsers that don't support PUT or DELETE" - RESTful Web Services, Leonard Richardson & Sam Ruby.
- Natsu 14y agoThis I agree with. But that comes a lot closer to honoring the semantics of the HTTP verbs, too. I do understand the need to be flexible sometimes, especially when some things aren't well-supported, but I cringe whenever I see GET requests changing application state.
- housecor 14y agoGreat point Natsu. I agree and have edited my post accordingly.
- kodablah 14y agoSome people resolve this with the X-HTTP-Method-Override header which I believe is a lot more clean. This is very helpful in situations where certain strict REST clients don't support PATCH (the underrated verb to help with partial updates).
- sopooneo 14y agoThe big question I almost never see addressed: Why would true REST be worth pursuing anyway? What's so good about it over other ways of setting up APIs? If I recall correctly, Fielding himself says that it may be detrimental to an individual organization in the short term, but if we all do it, it will eventually help make our APIs collectively interoparable.
- fideloper 14y agoThis is very interesting. The idea and requirement between ease of use and full-REST implementation is definitely worth discussing. Two Points: * Consistency could be very useful across web-services * Simplicity is exceptionally important If all API's were created with a 'full-REST implementation', that would comply with the need (Desire?) for consistency, however it would not necessarily be easier. What might be "hard": * Some limitations (firewalls, lack of knowledge) on PUT and DELETE * The debate on when to use PUT and DELETE * Editing headers to request content type (xml vs json etc) So the big question seems to be: What is the mix between consistency and ease of use? Perhaps we can be full-on REST but then make it easier with code libraries?
- dwood 14y agoI once asked Tim Berners-Lee about POST vs. PUT and he told me that POST was for insert (as in posting a nntp article) and PUT was for update. That's good enough for me.