News for hackers. Stuff that matters.
Re:Show HN: Deck of Cards – A playing card API by hartror on Sunday May 10, 2015 @11:50PM (#9522597)
Nice one! Good on you for building a thing and putting it out there.

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...

Re:Show HN: Deck of Cards – A playing card API by Kiro on Monday May 11, 2015 @01:28AM (#9522872)
> You are mutating state with HTTP GET

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?

Re:Show HN: Deck of Cards – A playing card API by xnxn on Monday May 11, 2015 @01:42AM (#9522913)
> Drawing a card is definitely a GET.

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.

Re:Show HN: Deck of Cards – A playing card API by Confusion on Monday May 11, 2015 @03:43AM (#9523245)
In some sense you are PATCHing the deck by removing a card.
Re:Show HN: Deck of Cards – A playing card API by hartror on Monday May 11, 2015 @04:42AM (#9523384)
I've yet to see a case for PATCH that couldn't be solved with more clarity for everyone involved by a new resource.
Re:Show HN: Deck of Cards – A playing card API by ryan-allen on Monday May 11, 2015 @03:24AM (#9523200)
I think it's more of a terminology thing, rather than 'GET me a card' you could 'POST remove 2 cards from the deck' and the side effect is the response tells you which cards were deleted.

But this kind of bike shedding drives me mad because oh my lord who gives a crap just build software and document it properly.

Re:Show HN: Deck of Cards – A playing card API by Confusion on Monday May 11, 2015 @03:44AM (#9523256)
I give a crap, because when I see an API, I expect a GET to be idempotent. If a coworker implemented this, there would be words.
Re:Show HN: Deck of Cards – A playing card API by whyaduck on Monday May 11, 2015 @12:46PM (#9526060)
Same here. Working on a large codebase where people "just build software and document it properly" without following standards is not fun. Not to mention that frequently people end up shortening that to "just build software". It's better to get in the habit of following good standards even on small projects before bad habits form.
Re:Show HN: Deck of Cards – A playing card API by wetmore on Monday May 11, 2015 @03:35AM (#9523225)
It's not necessarily bike shedding though. GET and POST have two different, widely-agreed upon semantic meanings. It's not just terminology.
Re:Show HN: Deck of Cards – A playing card API by hartror on Monday May 11, 2015 @02:39AM (#9523075)
As others have pointed out the HTTP verbs have meaning at a protocol level, trying to match a verb based on its English meaning is fraught with problems. Not least of which is the proxy problem I pointed out in my original comment.
Re:Show HN: Deck of Cards – A playing card API by Drakim on Monday May 11, 2015 @02:36AM (#9523066)
I would argue that "drawing a card" isn't merely an information look up (GET) but an action with consequences (POST).

Looking at the cards in your hands, if the server maintains your hand state, would be a GET though.

Re:Show HN: Deck of Cards – A playing card API by thedufer on Monday May 11, 2015 @11:46AM (#9525568)
It is acceptable for a client to retry a request that failed if it is a GET. This could happen if the server got your request but the response got lost, in which case you can't count on the deck having the right number of cards.
Re:Show HN: Deck of Cards – A playing card API by crimsonalucard on Monday May 11, 2015 @02:07AM (#9522993)
Why conform to arbitrary conventions when they don't make sense? Personally I think the best reason to conform to REST is because the user expects a "good" api to conform. Other then that is there any hard reason as to why it's "better" to strictly follow REST or even follow it at all?

Is an api that is consistent, fast and documented well, but uses only GET requests for everything including state changes really a horrible api?

Re:Show HN: Deck of Cards – A playing card API by vog on Monday May 11, 2015 @02:48AM (#9523106)
> Is an api that [...] uses only GET requests for [...] 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.2
Re:Show HN: Deck of Cards – A playing card API by alexhill on Monday May 11, 2015 @02:49AM (#9523110)
I agree with the spirit of your post, but using the right HTTP verbs can have real, actual consequences because of how some caches and clients behave. You're more likely to accidentally send multiple requests or get stale data when you're using GET.
Re:Show HN: Deck of Cards – A playing card API by jalfresi on Monday May 11, 2015 @06:54AM (#9523759)
DELETE a card from the deck. Return the card(s) drawn in the response body. Have a separate resource for the top of the deck:

DELETE /api/<deck-id>/top?count=2

------

200 Ok

8♣

10♥

Re:Show HN: Deck of Cards – A playing card API by hartror on Monday May 11, 2015 @07:00AM (#9523772)
DELETE is idempotent to quote a Stack Overflow answer on the subject:

> 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...

Re:Show HN: Deck of Cards – A playing card API by jalfresi on Monday May 11, 2015 @08:38AM (#9524191)
The example I gave is idempotent. Calling it n >0 times would result in the same side effects.
Re:Show HN: Deck of Cards – A playing card API by couchand on Monday May 11, 2015 @08:50AM (#9524260)
That's not what idempotent means. It doesn't mean it produces the same side effects every time, it means multiple calls are equivalent to a single call.
Re:Show HN: Deck of Cards – A playing card API by jalfresi on Monday May 11, 2015 @09:03AM (#9524342)
Gah! You're right. In that case POST would be the only acceptable option here.
Re:Show HN: Deck of Cards – A playing card API by anilgulecha on Monday May 11, 2015 @01:38AM (#9522897)
A PUT would work, with action=draw&count=2, or action=shuffle, and so forth.
Re:Show HN: Deck of Cards – A playing card API by nl on Monday May 11, 2015 @02:40AM (#9523077)
As a general rule "action" parameter is pretty non-RESTful.

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.

Re:Show HN: Deck of Cards – A playing card API by dghf on Monday May 11, 2015 @10:11AM (#9524842)
I thought URLs (including query strings) were opaque under REST?
Re:Show HN: Deck of Cards – A playing card API by vog on Monday May 11, 2015 @02:08PM (#9526637)
URLs are opaque, but the meanings of the HTTP methods aren't.
Re:Show HN: Deck of Cards – A playing card API by dghf on Monday May 11, 2015 @03:19PM (#9527211)
I'm not questioning that; I was questioning the statement '"action" parameter is pretty non-RESTful'. If URLs are opaque, why is it non-RESTful? Or is the point that if you're using query-string parameters, then by definition you're using a method that's supposed to be safe or idempotent?
Re:Show HN: Deck of Cards – A playing card API by vog on Monday May 11, 2015 @05:52PM (#9528097)
If you used different HTTP methods, you'd already know which one to use, and don't need the action parameter. So the usage of the "action" parameter usually implies that that requests are all the same method. And if we don't want to violate the HTTP standard, that method must be neither GET/HEAD, nor PUT nor DELETE (as surely some actions are non-idempotent).

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.

Re:Show HN: Deck of Cards – A playing card API by dghf on Tuesday May 12, 2015 @03:13AM (#9529999)
> If you used different HTTP methods, you'd already know which one to use, and don't need the action parameter.

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)?

Re:Show HN: Deck of Cards – A playing card API by kikibobo69 on Monday May 11, 2015 @01:40AM (#9522906)
PUT should be idempotent, though.
Re:Show HN: Deck of Cards – A playing card API by bdcravens on Monday May 11, 2015 @02:12AM (#9523008)
Could each draw return a draw_hash, that is usable only once? Not only could you then have idempotent draws, you could easily embed it as hypermedia,a previous hash could be sent to a hand_history to return an array of point in time data
Re:Show HN: Deck of Cards – A playing card API by voltagex_ on Monday May 11, 2015 @12:29AM (#9522706)
>good opportunity to make the API self documenting & navigable with a hypermedia format. (eg HAL, Siren, JSON-LD)

Other than learning, what's the benefit here?

Re:Show HN: Deck of Cards – A playing card API by hartror on Monday May 11, 2015 @12:35AM (#9522727)
I assume you mean what is the benefit of hypermedia?

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).

Re:Show HN: Deck of Cards – A playing card API by iamflimflam1 on Monday May 11, 2015 @04:06AM (#9523299)
I don't see much benefit in martin fowler's example

  <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.

Re:Show HN: Deck of Cards – A playing card API by evanspa on Monday May 11, 2015 @10:03AM (#9524772)
Clients of a hypermedia REST API are supposed to have a priori knowledge of the link relations (the "rel" attribute). The fact the rel in this example looks like a URI is sometimes used as a convention (i.e., if the API supports it, a client may do a GET against the rel value, and get back a human-readable description of the purpose of the rel).

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.

Re:Show HN: Deck of Cards – A playing card API by hartror on Monday May 11, 2015 @04:39AM (#9523371)
I agree though I expect Fowler may argue that that is what the HTTP verb OPTIONS is for. Amundsen on the other hand likes his hypermedia more explicit and I tend to agree with him.
Re:Show HN: Deck of Cards – A playing card API by iamleppert on Monday May 11, 2015 @01:58PM (#9526576)
1. His documentation is better than HAL, Siren, JSON-LD. It's a nice page.

2. GET makes sense here. If anything, it would be a PATCH. But it's silly to get bogged down in details.

Re:Show HN: Deck of Cards – A playing card API by vog on Monday May 11, 2015 @02:08PM (#9526638)
> 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

https://news.ycombinator.com/item?id=9523066

https://news.ycombinator.com/item?id=9525568