I agree. However, this is the first API I've seen where a mutable GET actually makes sense. Drawing a card is definitely a GET. How would you do it instead?
I see where you're coming from ("I'm drawing / taking / GETting some cards"), but drawing cards is not an idempotent action. I would implement it as a POST.
But this kind of bike shedding drives me mad because oh my lord who gives a crap just build software and document it properly.
Looking at the cards in your hands, if the server maintains your hand state, would be a GET though.
Is an api that is consistent, fast and documented well, but uses only GET requests for everything including state changes really a horrible api?
Yes, it is. Because HTTP clients (including browser) rely on the common method properties as defined by the HTTP standard (GET having no side effects, PUT being idempotent, etc.). The simplest example is caching / proxying, but there is other behaviour.
I strong recommend acutally taking a look at the HTTP standard. The RFCs such as RFC 7231 are well organized and human readable. For the definition of the HTTP verbs, see:
RFC 7231 Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content
4.2 Common Method Properties
https://tools.ietf.org/html/rfc7231#section-4.2DELETE /api/<deck-id>/top?count=2
------
200 Ok
8♣
10♥
> Idempotence refers to the state of the system after the request has completed
> ...
> The key bit there is the side-effects of N > 0 identical requests is the same as for a single request.
http://stackoverflow.com/questions/4088350/is-rest-delete-re...
Sometimes RPC-style interfaces like that are ok, but don't pretend that they are RESTful.
Also PUTs are supposed to be idempotent, so don't use a PUT for this.
In other words, an action parameter which is actually used and which doesn't violate the HTTP standard, well, that almost certainly means that all requests are POST requests.
However, if all requests are POST, no matter if they are side-effect-free or not, no matter if they are idempotent or not, then this is not very REST-like.
Note that it is not important whether you think this argument does or doesn't holds for your particular API. My point is that this whole judgement is solely about HTTP methods, and has nothing to do with URLs being opaque.
But the examples given by anilgulechas were 'action=draw' and 'action=shuffle'. Neither are idempotent, let alone safe, so presumably the only method to use in either case would be POST (notwithstanding anilgulecha's suggestion of a PUT).
So we need to distinguish between POSTs requesting a draw, and POSTs requesting a shuffle. Two options:
a) indicate it in the POST's body
b) indicate it in the URL.
If we go for (b), the query string seems as good a place as any.
What have I got wrong? Where would this violate REST (or the HTTP spec)?
Other than learning, what's the benefit here?
Martin Fowler does a good job explaining it (http://martinfowler.com/articles/richardsonMaturityModel.htm...).
As does Mike Amundsen (http://www.infoq.com/presentations/Building-Hypermedia-API).
<openSlotList>
<slot id = "1234" doctor = "mjones" start = "1400" end = "1450">
<link rel = "/linkrels/slot/book" uri = "/slots/1234"/>
</slot>
<slot id = "5678" doctor = "mjones" start = "1600" end = "1650">
<link rel = "/linkrels/slot/book" uri = "/slots/5678"/>
</slot>
</openSlotList>
Each slot now has a link element which contains a URI to tell us how to book an appointment.
Well, not really - we can only guess that by the fact that the link ends in "book".We also don't know if we are supposed to GET, PUT, DELETE, POST.. or what data we are supposed to send to the url to actually make the booking.
In the human readable description of the "/linksrels/slot/book" link relation, information should be given about what generally can be done with such links (like if GET or POST is supported, etc). This allows you to build your client applications. The value of the actual link (the 'uri' attribute) should be completely opaque to the client.
2. GET makes sense here. If anything, it would be a PATCH. But it's silly to get bogged down in details.
Those "details" are quite important, as already explained in several other comments:
https://news.ycombinator.com/item?id=9523225
https://news.ycombinator.com/item?id=9523106
https://news.ycombinator.com/item?id=9523075
A few comments/suggestions:
* You have DEBUG = True in your production Django config. (eg. http://deckofcardsapi.com/api/)
* You are mutating state with HTTP GET, this is an anti-pattern for a number of reasons. The common one I use with people I coach is that browsers/proxies will happily cache GET requests unless told not to, but there are a number of other reasons if you read up on REST [1].
* Being a public API in a well known domain this is a good opportunity to make the API self documenting & navigable with a hypermedia format. (eg HAL, Siren, JSON-LD) [2]
[1] http://martinfowler.com/articles/richardsonMaturityModel.htm...
[2] http://sookocheff.com/posts/2014-03-11-on-choosing-a-hyperme...