11 ms·
Some REST best practices
- sjtgraham 12y agoMost of this has little to do with REST at all, e.g. URLs don't actually matter in REST (because of HATEOAS) and should be considered opaque. This is more HTTP API best practises (best practise in the author's opinion). REST has become a meaningless term.
- eleumik 12y agoI agree. Links must be in the response, that's the point. Also I dont' understand this hierarchical path mania that brings one to make complicate things where URIs are parsed / produced. I use the query string for this in general, is much easier, only if I have some special needs I don't.
- jimktrains2 12y ago> This is more HTTP API best practises I'd disagree. If I were critiquing a non-REST API over HTTP, I wouldn't get upset about requiring a call to POST /processOrder at all, whereas I'd begin to convulse if they said it was a REST API.
- tom_b 12y agoYes. As a hacker who leans on books, blogs, and well-defined principles, RESTful api design resources have often been much more http RPC oriented. Hackers should pay attention to: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hyperte... I have also found collection+json and hypermedia application language (HAL) to be useful. Plus, I have spent a bunch of time reading the Restful Web APIs book from O'Reilly. Useful for me, as a relative newbie, in providing some logical foundation to start from . . .
- EdwardDiego 12y agoDo you have an example of an API that meet's Fielding's definition of REST?
- tom_b 12y agotl;dr: Not that I've dug into. I've found a number of people who point at the Github api as a good example of a RESTful api that includes hypermedia links for clients to follow rather than constructing URI requests manually. It looks good to me.
- jessaustin 12y agohttp://roy.gbiv.. http://roy.gbiv... Money quote: REST is intended for long-lived network-based applications that span multiple organizations. If you don’t see a need for the constraints, then don’t use them. That’s fine with me as long as you don’t call the result a REST API.
- protonfish 12y agoI must disagree. REST is defined by four interface constraints: http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_1_5 http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch... and identification of resources is the first principle. This functionality is implemented by URLs in HTTP and is therefore critical. HATEOAS (the 4th principle) also seems to be gravely misunderstood. It only means that the API should have a version that is fully useable in a web browser.
- sjtgraham 12y agoIncorrect. Resources are identified by URIs, but they are opaque, n.b. The Opacity Axiom "The only thing you can use an identifier for is to refer to an object. When you are not dereferencing, you should not look at the contents of the URI string to gain other information." http://www.w3.org/DesignIssues/Axioms.html#opaque http://www.w3.org/DesignIssues/Axioms.html#opaque
- wahnfrieden 12y agoWhat the URLs look like is not a concern of REST though. Can you cite your latter point, since that's contrary to how I've seen HATEOAS explained? Many libraries do expose a browser-navigable form of the API, but I can't see how that's how it's originally defined nor it being a requirement.
- protonfish 12y agoAre you saying that it's just as good to have a URL be /fj3849-2qfjimpa as /customer? I agree that it is not strictly a REST principle, but in an API clarity matters. If we are talking about good practices, would your rather work with an REST API with readable, concise URLs or not? Maybe I am missing the point but the URL is one of the major building blocks of REST and choosing quality ones is a large part of API design. I stated that HATEOAS is widely misunderstood so it isn't surprising that there are conflicting descriptions out there. No matter what your interpretation, this principle is about hypermedia and application state and says nothing about what a URL should or should not be.
- jayvanguard 12y agoThis debate was settled almost a decade ago. URL forms don't matter in theoretical dissertation REST, but 15 years of practice has firmly decided they are indeed a core part of real-world REST. HTTP based web services existed before Roy's dissertation and while the formalizing of them helped them mature rapidly, the idealistic principles aren't the final word on the subject anymore. Real world practice now is.
- icebraining 12y agoURLs don't matter for 99% of actual REST usage. Your browser doesn't care if you're POSTing to /posts/new or to /jeskew. "APIs" are the exception.
- jayvanguard 12y agoAPIs are what we are talking about.
- icebraining 12y agoMy point is that APIs are an exception mostly because developers are conditioned by the RPC "APIs" mental models, which doesn't take effect when they're thinking about a "website" instead, not due to some fundamental technological difference.
- dragonwriter 12y agoThat's because the modern web itself is a REST API, whereas most of the things that call themselves "REST APIs" aren't.
- mcguire 12y agoAnd having extra irrelevancies to worry about such as "Version your API", "Use nouns, not verbs", singular versus plural, and nested resources are the consequences of being "practical".
- hawleyal 12y agoURIs matter and REST matters because people have been using them incorrectly for so long. Common mistakes like putting verbs in URIs instead of using HTTP methods. You are correct though, about the design of verbs don't matter (outside of conventions) as long as everything is done correctly.
- tptacek 12y agoJust off the top of my head: if you think of verbs exposed in URLs as a common REST mistake, you may not have fully absorbed the HATEOS concept. If you have HATEOS, you're unlikely to have verb URLs.
- k__ 12y agoany good resources to HATEOS?
- metaphorm 12y agowell, its just wikipedia, but its actually well written page on the concept, in my opinion http://en.wikipedia.org/wiki/HATEOAS http://en.wikipedia.org/wiki/HATEOAS key concept: > "The principle is that a client interacts with a network application entirely through hypermedia provided dynamically by application servers. A REST client needs no prior knowledge about how to interact with any particular application or server beyond a generic understanding of hypermedia. By contrast, in a service-oriented architecture (SOA), clients and servers interact through a fixed interface shared through documentation or an interface description language (IDL)." a truly RESTful service that follows the HATEOAS pattern doesn't require documentation to be hosted separately. it will supply all the information necessary directly through the RESTful service.
- k__ 12y agoHm okay. The key concept I understood but I don't get how clients and servers have to be, to just "get" each other in the way HATEOAS implies.
- metaphorm 12y agoyou're right, this is really about making a good JSON api that maps CRUD operations to HTTP verbs. REST is often used as a shorthand for that, though its not technically 100% accurate. that said, it was still a good article. I agree with the author on his best practices for JSON API design.
- ultramancool 12y ago> REST has become a meaningless term. Indeed, and this is why I think "RESTful" APIs are a huge problem - they're largely undefined. We have SOAP for defining these things formally without the need to worry about implementation differences. Unfortunately it was essentially abandoned because it was too complicated and excessive. It would be really interesting to see something SOAP-like with some more modern features and made a bit simpler.
- dllthomas 12y agoSimple Object Access Protocol was too complicated.
- ultramancool 12y agoUhm, I mentioned that in my post. Thanks for re-iterating? Personally, I thought it was pretty simple, but I come from a land of CORBA. I don't think the ultimate solution for "this structure is too complicated" should be "fuck structure altogether" though. Rather, we should try to arrive at a simpler structure.
- dllthomas 12y agoI wasn't criticizing your post. I was spelling out the name, because the tension between "Simple ..." and "... too complicated" amused me.
- 12y ago
- pbreit 12y agoThat is more of an indictment on how poorly REST has been presented. It remains mostly impossible to get a very good definition of REST or point to an API/whatever that is a good example of REST.
- serve_yay 12y agoI think that is at least in part because for a few years, every time someone thought they had a RESTful system, some genius would come through and declare it non-RESTful on account of not following some rule or other. So "RESTful" came to mean a type of HTTP API that tends to look a certain way. And so of course URLs matter. Saying something is "RESTful" is a surefire way to find out the ways in which it fails to match up with what some obscure document says.
- euph0ria 12y agoWhat is the best practice regarding filtering? Suppose you'd like to filter the artist's albums to only show albums from a range of years (2005-2014).
- grandalf 12y agoI think a standardized query interface for the index make the most sense. I prefer this to nested actions unless there are very few typical searches.
- shangxiao 12y agoQuery parameters on the collection. Dealing with ranges is always a tricky one though and I've seen different REST libraries use different querying.
- shangxiao 12y ago> use nested routing for a cleaner design I think this is actually quite debatable and I've seen a lot of people argue that nested resources are an anti-pattern. I only ever use nested resources myself when the child resource is existentially dependent on the parent.
- madeofpalk 12y agoI think what he's describing, or at least what I do, is when you get all albums belonging to an artist. GET /artist/8/albums { albums: [89, 93] } GET /albums/89 { album: { id: 89, title: 'Blah' } }
- shangxiao 12y agoIn this case I would either make albums a field of artist, or just leave it off altogether and just filter /albums based on the artist foreign key.
- moron4hire 12y agoWhat about collaborations? The nested hierarchy implies a directed tree structure, but the relationships are really a graph. And I've personally found no more insidious of a problem in data design than trying to shoehorn a graph into a directed tree.
- hawleyal 12y agoThe relationships in URIs are abstractions anyway. The data is not actually stored at /artist/8/albums or /albums?artist=8. Both are abstractions of whatever underlying system is used to store the relationships.
- danielnaab 12y agoMore flexible: GET /albums?artist=8 GET /albums?artist=8&artist=10 GET /albums?title='Blah'
- hawleyal 12y ago
- grandalf 12y agoOne very bad practice that is quite common is using status codes in application specific ways and not including a standard error payload. One way to think of it is that status codes are part of the transport, and your own application logic (validation, application error conditions, warnings, etc.) should never use HTTP error codes. A dumb proxy server should be able to cache any response (including its status code) on a GET or HEAD without needing to know about any application logic.
- josai 12y ago> One way is to do is to pass the API version in the URL (/api/v1/...) If you do it like this, how do you then deal with 1.0.1? Especially in a framework like rails, where paths basically map to a folder structure? I agree it's much nicer to be able to test manually when you have the version in the path but it significantly reduces flexibility later on.
- m_t 12y agoWhat we did for this case was to "not break the API during a minor version". For instance, only return more data and not less. Do not change the conditions/meaning of errors. If you need to, then it's the right moment to switch to v2.
- Pxtl 12y agoExactly. All minor/revision API changes should be backwards compatible. You can add new optional parameters and new methods/objects, but you can't change the semantics of anything existing. If you need a breaking change, that's time to increment the major number. Besides that, who'd want to support that many versions running live?
- jobu 12y agoAPI Versioning is for your clients, not your code. The only reason to change the version is if you're going to make breaking changes that old clients can't process. It's possible to rewrite an API in a different language and still have it be the same version URI.
- steakejjs 12y agoOne thing I've noticed that will become increasingly important in the future is for JavaScript APIs it would be really nice if you had a per user path, for example: api.com/steakejjs/v1/ This way, user's of your API can implement Content-Security-Policy in a secure manner (where an attacker can't use your 3rd party API to exfiltrate data). It's not like there aren't other ways to exfiltrate data, but this will definitely help.
- josai 12y ago> Here are some bad examples : > /retreiveClientByOrder?orderId=1 I note the author didn't go on to demonstrate a better way of doing this. What would he recommend, /clients?by_order_id=1 ?
- misja 12y agoUsing sub-resources, you get something like this: GET /orders/1/clients
- jagger27 12y agoSo mapping this request onto a SQL database would be something like... SELECT * FROM orders WHERE client_id = 1 And for GET /clients/1/orders it seems like in practice it would be the same relation since it would be wasteful to store two tables. Is this roughly correct?
- mattmanser 12y agoNo. Think of it as "for order 1 list all clients", so it would be: SELECT * FROM clients WHERE client_id IN (SELECT client_id FROM orders WHERE order_id = @order_id) The GET /clients/1/orders is what would result in your query (for client 1 list all orders).
- jobu 12y agoHere are a couple more lists of Best Practices for REST APIs. http://blog.mwaysolutions.com/2014/06/05/10-best-practices-for-better-restful-api/ http://blog.mwaysolutions.com/2014/06/05/10-best-practices-f... http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api http://www.vinaysahni.com/best-practices-for-a-pragmatic-res... The Github team does a pretty good job of incorporating modern best practices as well, so I often use their API as a reference: https://developer.github.com/v3/ https://developer.github.com/v3/
- protonfish 12y agoI'd say maybe half of these are actual good practices. In my experience, these are not: I agree that keeping resource names consistent is good, but using plurals is not the only, and probably not the superior, solution. Versioning is an idea that gets talked about a lot but can easily create more problems than it solves. Small improvements in APIs should be backward compatible and major ones should be new APIs. Whatever you do, putting "v1" in the middle of your URL is the wrong way to do it. (And so is putting "api" in your URL. It's better to keep your URLs clean of ambiguous and redundant information.) Nesting resources is an anti-pattern that quickly creates a mess. I've learned this the hard way so please don't repeat my mistakes. The 3rd principle of REST interface constraints is "descriptive" error messages. It is better to be clear and thorough than consistent. Consistency gets you nothing, especially if it is consistently bad.
- hesselink 12y agoThe article gives some motivation for its best practices, you do not. Would you care to provide some? > using plurals is not the only, and probably not the superior, solution. Why? > Whatever you do, putting "v1" in the middle of your URL is the wrong way to do it. Why? > Nesting resources is an anti-pattern that quickly creates a mess. Why? Edit: not sure why the downvotes. I'm genuinely interested, but the parent doesn't contain much useful content.
- protonfish 12y agoI suppose one must first define the qualities between a good and a poor API. I would say that it is the same as any code: The design should be readable, maintainable and modular. The plurals or not thing isn't a big deal. I really just object to the author picking one and claiming it's better with justification. Putting "vi" in your URL decreases both readability and modularity. All things being equal, concise URLs are more readable. "v1" are extra characters without significant benefit. It also creates huge maintenance overhead. How many APIs do you think you can simultaneously maintain well? I am happy with one good one myself. Every extra new version you create (as opposed to gracefully improving the existing one) is more technical debt. Let's take the nesting example: /artists/8/albums. What if you want to access an album by itself? You also need an /albums resource so you've just created two resources when you need only one. The /artists/8 response should include a list of albums that hyperlink to the /albums resources. If you absolutely have to have a clean list (without the artist header information, just filter it with a query string /albums/?artist=8. This accomplishes the same thing in a more predictable and consistent way without magic URL params. The major benefit of this type of design is it makes tracing execution from the interface to a code location much clearer by avoiding spaghetti URL routing.
- shdon 12y agoThe use of 401 Unauthorized is an annoying one because of a little thing in the spec: The response MUST include a WWW-Authenticate header field (section 14.47) containing a challenge applicable to the requested resource. AFAICT, This makes it makes it inapplicable to REST APIs that do not use basic or digest authentication, at least without violating the spec for the 401 response code. Is there something that I've missed?
- justinsb 12y agoWhy not pass a dummy value to satisfy the spec?
- dragonwriter 12y agoBecause a dummy value satisfies the syntax but not semantics of the spec.
- hawleyal 12y ago400 Bad Request is often a better, albeit generic, option.
- deleted 12y ago[deleted]
- wnevets 12y agois it just me or no one can agree on what the best practices for a REST API are?
- thibauts 12y agoNo wonder. REST manipulates resources but not every software service maps to resources, or (very) painfully so. This is easy to overlook when you have not had to implement a substantial service that is not a simple storage interface in this fashion. It might be tempting to write an article not trying to solve or even address this but it wrongly makes things appear more simple than they are. REST often tries to map a graph of resources on a tree (the URL space). This problem is more related to the web and naming in general yet there are many possible solutions and no clear rule to apply, leaving plenty of room to blind alleys and time lost pondering which option is the least ugly. I'm not blaming REST here but this still is a major problem seldom addressed in articles. REST, HATEOAS and friends lean a lot on the theory side seducing you into thinking machines will use your API without human intervention and make you lose time building for a non-existant use case (and your boss doesn't want to make automated access to his data that easy by the way). I suspect they will succeed at the exact same time the semantic web succeeds. REST tries to convince you that everything will map cleanly to the HTTP standard, and it's pretty close, but most of times it falls short in a way or another. In pratice most blog posts will tell you to use nouns, to rely on status codes, etc, yet every other popular API will derail in a way or another when faced with the cases that don't fit. To sum it up, theory is cute, reality is less. Having a clean scheme where everything could theoretically fit is very seducing to any software engineer. In a way it feels like the holy grail, and it could be, but maybe it's not. And if it's not, trying to make everything fit in the wrong model could just be an awful waste of time. I still like the fact that it forces my brain to think in a non-intuitive way about some problems, but well. Our profession is plagued with micro-cults, holy grail models, silver bullets, magic blueprints we try to cast everything we can get our hands on in. MVC comes to mind. I think REST is becoming my second favorite.
- thecodemonkey 12y agoThis is a great article, I wrote a similar blog post recently [1] [1] http://scotch.io/bar-talk/designing-a-restful-web-api http://scotch.io/bar-talk/designing-a-restful-web-api
- pmontra 12y agoThere is a draft RFC for returning errors in APIs based on JSON. http://datatracker.ietf.org/doc/draft-ietf-appsawg-http-problem/?include_text=1 http://datatracker.ietf.org/doc/draft-ietf-appsawg-http-prob... Their example: HTTP/1.1 403 Forbidden Content-Type: application/problem+json Content-Language: en { "type": "http://example.com/probs/out-of-credit", "title": "You do not have enough credit.", "detail": "Your current balance is 30, but that costs 50.", "instance": "http://example.net/account/12345/msgs/abc", "balance": 30, "accounts": ["http://example.net/account/12345", "http://example.net/account/67890"] } type, title, detail and instance are attributes defined by the spec. balance and accounts are extra attributes added for this error. I suppose that if I want to return validation errors to decorate an input form I'll have to add many custom attributes like those.
- neya 12y agoIf you're coming from a Rails background, then you know, most of this stuff is actually done (and also documented) for you by the framework itself, if you use its scaffolding feature. One more reason why I love Rails and the people behind it.
- ericcumbee 12y agoI found "Build APIs you won't hate" to be an excellent resource. Probably somewhat of a beginners text, but I found it to be extremely clear and concise, and very readable for the amount of information it covered. It was also very pragmatic about when to adhere to REST dogma and when to deviate from it. https://leanpub.com/build-apis-you-wont-hate https://leanpub.com/build-apis-you-wont-hate
- freework 12y agoAs an experienced developer who as had to implement dozens of API's over my career, therre are two things that I care about: 1. Documentation - If I have to spend the next month doing trial+error to get your API working, thats no good. The best APIs have a page that describes how get up and running quickly. 2. Good error messages - When something goes wrong I want to know what went wrong. The error message being in a consistent format isn't that important, as long as there is a description of what happened. "Oops, an error occurred, try again later" is not a good error message. Most of the stuff in this article is superficial stuff that I don't think matters.
- personZ 12y agoMost of the stuff in this article is superficial stuff that I don't think matters. What the article seems to describe are practices that generate consistent, predictable RESTful APIs, which is exactly how you yield easy to use APIs. This saves both the creator and consumer's time, as debate and decisions over deviations are avoided. I'm not quite sure why so many comments have gone so negative -- this is hardly a revolutionary piece, yet many of us are creating or dealing with APIs that could do well to take some advice.
- cbd1984 12y agoBetter documentation is a non-trivial example application that, one, exercises all "normal" uses of the API, and, two, shows what the API developers consider to be best practices, all the way through. Let me into your minds. Show me how you think I think. If you don't know how the people consuming your API think, your API is going to be pretty bogus. If your way of thinking is inimical to me, fine and dandy. Just give me a reasonable way to find out which isn't reading hundreds of pages of Javadoc or similar. And if the example contains copy-and-pastable code, or reusable functions, so much the better. Make the licenses align, even if the code which implements the API is fully proprietary, and things will work out just fine. Oh, and if you can't keep your example code working, that says something I need to know, too. Something nasty.
- daigoba66 12y agoAll too often we'll receive a "specification" document which just lists a bunch of URL fragments with the word GET or POST next to them. If we're lucky, we'll get a sample of the request and response body. What we're left with are the two problems you described. We have no idea how to actually _do_ anything with the API. And when things don't appear to work, we're left guessing. Some of the best API "guides" are the ones that break things down by use case and describe how to achieve it. For example, I'm a fan of GitHub documentation: https://developer.github.com/v3/issues/#create-an-issue https://developer.github.com/v3/issues/#create-an-issue.
- shill 12y agoThere can never be enough articles and books supporting API best practices. Here are two of my favorite REST resources (pun intended). Richardson Maturity Model: steps toward the glory of REST http://martinfowler.com/articles/richardsonMaturityModel.html http://martinfowler.com/articles/richardsonMaturityModel.htm... RESTful Web Services Cookbook: Solutions for Improving Scalability and Simplicity http://www.amazon.com/gp/product/0596801688 http://www.amazon.com/gp/product/0596801688 And I am looking forward to widespread adoption of the REST problem standard posted here a few weeks ago. http://www.ietf.org/id/draft-ietf-appsawg-http-problem-00.txt http://www.ietf.org/id/draft-ietf-appsawg-http-problem-00.tx...
- thewarrior 12y agoWhat status code should one return when the server receives incorrect credentials for an authentication API ? 401 - Unauthorized looks like the correct answer, but if you read the Wikipedia article 401 is specifically intended for HTTP Authentication using usernames and passwords set in the headers. I recently ran into a situation where a third party library on receiving a 401 proceeded to then ask for HTTP credentials and try to resubmit the request when actually the server indicated that we had just submitted the wrong username/password for our login API (which doesn't even use HTTP Auth). We don't use WWW-Authenticate headers but the third party library seems to be following the standard. So should we be returning 400 instead ?
- dragonwriter 12y ago> So should we be returning 400 instead ? 403 Forbidden (or 404 Not Found if you don't want to leak information about the existence of a resource to unauthorized users) is probably the right one to use when the access is unauthorized in the general sense, but not the specific kind of HTTP Authentication issue that 401 addresses.
- protonfish 12y agoThe spec for 403 states that "Authorization will not help and the request SHOULD NOT be repeated" so I don't think that is appropriate either. It's a good question though. I've always used 401 and haven't run into problems but I can see why it's probably not correct. I am sure that 400 (with a proper response body explaining the authentication requirements) would not be wrong, but I am uncertain if it is best.
- dragonwriter 12y ago> The spec for 403 states that "Authorization will not help and the request SHOULD NOT be repeated" so I don't think that is appropriate either. I think that in context "authorization" in 403 can only be understood to mean the same thing as is authorization is implied to mean by the use of "Unauthorized" with the specific definition in 401 -- that is, reauthentication via the HTTP authentication methods. Under that view, 403 (and, to avoid leaking information, 404) fits. 400 does not seem to fit: it is not a generic code that fits the whole class of things in the 4xx series. Its definition is specifically "The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications." But the problem that is being identified is not malformed syntax.
- zkhalique 12y agoI personally think that POST should hit an existing resource and create a new, related one. While PUT should hit an existing resource and modify it (if permissions allow). GET and DELETE are pretty obvious. Those are the conventions I use when I create REST interfaces.
- fixermark 12y agoPost is missing advice on what to do to notify the client that the request is completely serviceable but should be retried later (i.e. Twitter's 420, or the actual RFC standard 429 [http://tools.ietf.org/html/rfc6585] http://tools.ietf.org/html/rfc6585]). This is key for modern services.
- EdwardDiego 12y ago> Twitter's 420 ...really Twitter?
- fixermark 12y ago"Enhance your calm." ;) https://dev.twitter.com/overview/api/response-codes https://dev.twitter.com/overview/api/response-codes Was superseded by the RFC standard 429 in API version 1.1.
- rafekett 12y agothere are lots of problems (particularly with versioning/backwards compatibility) that using better protocols (i.e., protobufs) can solve.
- krick 12y ago> For a clean and conscice structure, you should always use nouns. Well, yeah, it's what everyone says, but not so easy to do in practice. Especially in complex apps there's a lot of stuff that isn't actually creating, updating or deleting an object, it is semantically an action. Say, action "send email" (and not some random email, but related or even defined by some business object you are referring to). Or in bookkeeping apps you often need something like "recalculate", which you probably wouldn't like to think of as "updating" because it isn't "take these values and apply to that object", but rather "hey, it's time to make some decision: please run some process (probably, with side effects) and tell us what the result is". Or it might be an action like "moveToQueue<Name>". Or better yet, you explicitly are telling your system to make some interaction with third-party service which is essentially imperative (like GDS, or some external trading API or whatever that isn't an object for your system, but really more like a service for which your app is just a friendly gateway). It is a little bit hard to think of good example right away, because if there is action "purchaseTicket" and there's no object "ticket" in your system you might ask WHY there's no object ticket in your system, but in all specific enough systems there always are situations like this, and mostly for some good reason. And yeah, there's also decisions made for performance sake or simplicity of client-app (like some frontend-side "action queue" so that you can use reactive programming on front-end in more natural way). So what do I do then? All URLs like "/user/123/order[s]"(PUT,GET,...), "/product/321/comment[s]"(PUT,GET,...) and, suddenly "/sale/copyToAnotherService"? Now that kind of inconsistency is something I really don't like. …And while I was writing the last one I though about: how should look url for something like "getRecommendedProducts" which depends on both user and product? Now writing nouns/action names is a bit messy and so not-RESTful, but you always are able to write exactly what you mean by that request.
- baddox 12y agoFor sending an email, what's wrong with a POST to /email? For "recalculate," it seems like a POST to /stats_report would be reasonable.
- krick 12y agoIt depends, but POST to /email is more like "create new email template". As for "recalculate" what I mean is completely different from report. It is that there's some specific state of some object, when all info is already in the system and user has no control over it, but some values (depending on other values that all are already there) are denormalized and specific command from competent user is required to make it happen. For example, thing we "recalculate" might be balance or comission, but it cannot happen automatically, as some human has to verify manually that some parts of that process have been done properly.
- Johnie 12y agoOne minor nuance I use is adding a trailing slash to indicate resource vs custom verb. GET /products/ : will return the list of all products POST /products/ : will add a product to the collection GET /products/4/ : will retreive product #4 PATCH/PUT /products/4/ : will update product #4 POST /products/4/someCustomVerb : custom verb
- shocks 12y agoWe use jsend[1] for our responses. 1: http://labs.omniti.com/labs/jsend http://labs.omniti.com/labs/jsend
- kylequest 12y agoThis is a much (much :-)) better post about "REST"/"HTTP" API best practices: http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api http://www.vinaysahni.com/best-practices-for-a-pragmatic-res...
- nateabele 12y agoStopped reading at "Version your API". Clearly this guy has no idea what he's talking about [0]. [0] https://twitter.com/fielding/status/376835835670167552 https://twitter.com/fielding/status/376835835670167552
- 4326KFxu 12y agoThis is is a genuine question: if you don't version your API somehow, then how do your clients handle breaking changes?
- nateabele 12y agoVersion numbers simply represent a way of managing change over time. They certainly aren't the _only_ way, nor are they the most ideal in all situations, but they certainly are the most simple, accessible, and explicit, and they don't require a lot of planning ahead. By contrast, the reason why designing real REST services is hard is because you actually have to _design_ them. This requires long, hard thinking about the domain of the problem at hand, and as such, doesn't square well with our "agile" methodologies of week-in and week-out iterative hacking. Much as I typically loathe self-promotion, I did give a talk on this recently that enumerates some design strategies: https://speakerdeck.com/nateabele/designing-hypermedia-apis https://speakerdeck.com/nateabele/designing-hypermedia-apis -- check out slides 8-20.
- slowmovintarget 12y agoI tend to subscribe to the hybrid approach here: http://codebetter.com/howarddierking/2013/09/12/versioning-restful-services-v2/ http://codebetter.com/howarddierking/2013/09/12/versioning-r...
- Paul_Morgan 12y agoI'd accept both singular and plural. At least redirect one to the other.
- sre_ops 12y agoWell, if you want to never write anything that scales yes, those are in fact the correct practices for writing bone-headed APIs for applications that would blow up with 20k concurrent users doing simple GETs. If for some unknown reason you want to write APIs that don't go down faster than a 15 year old girl faints upon stumbling onto a boy from 1D in a local McDonalds you should: a) use verbs b) separate heavy end point from light end points c) make URL easy to parse by load balancers and proxies