
A bird's eye view on API development - TheEdonian
http://blog.madewithlove.be/post/birdseye-view-on-api/
======
Cakez0r
Why is it considered best practice to use the content type header for API
versioning? It always seemed like a hack to me. Url versioning makes much more
sense if you consider that your API is a resource and the content of your API
is a subresource. E.G. GET /v1/post/1/comment/456 would be semantically
equivalent to "give me comment with id 456, which belongs to post with id 1,
which belongs to api of version 1".

~~~
subliminalbrad
The URL is meant to represent a specific resource. You're requesting a comment
resource, not a version of a comment resource. It's semantically inappropriate
and may lead to unnecessary complexity.

There is an HTTP concept created specifically for this idea. Why not use it?

------
tomp
Can anyone explain why using different verbs (PUT, PATCH, ...) is preferable
to using just POST with an additional parameter (e.g. POST action="add")? It
seems like the author's distinction between POST, PUT and PATCH seems rather
arbitrary...

~~~
snarfy
POST action="add" is not RESTful. It's procedural. It doesn't take advantage
of all the http caching mechanisms that come into play with the web that you
get for free with a resource based design. You should PUT the resource.

~~~
tomp
> POST action="add" is not RESTful. It's procedural.

Can you expand on what you mean by this? In particular, how could HTTP
catching mechanism work with POST requests, if the purpose of POST is to
_change_ something on the server (so the request should always reach the
server)? And in what way is PUT handled differently (by browsers, by proxies,
by servers)?

~~~
mnutt
It's just conventional. If a PUT fails, you (and others) know you can safely
retry it multiple times without having to worry about it having any other
effects, like duplicate rows. The concept is called idempotence.

~~~
tomp
Oh, so basically `PUT` is just like a `POST action="add" id="XYZ"`? In any
case, that only works if the ID can be known in advance (which e.g. isn't
possible if you want sequential IDs).

~~~
keithb-
No, POST is create and PUT is update[1]. In the RESTful world, PUT uses a
specific URL for that entity, e.g. PUT /contacts/rich-hickey: there is only
one Rich Hickey and I'm going to update his contact info with the body of the
request. Check out the Decision Flow Diagram, it is really awesome[2].

There is probably no single reason why you should _never_ use POST when you
need PUT or DELETE. This is mostly an implementation choice, but if you are
using a Repository or DAO pattern on the server side, it might be easier to
understand if all of the semantics align nicely, e.g. HTTP<POST> -> OOP<Add>
-> SQL<CREATE>, HTTP<PUT> -> OOP<Update> -> SQL<UPDATE>.

IMHO using a parameter for method name is a call-by-name strategy that, in
this case, is a level of abstraction that just isn't necessary. In other
words, there is really nothing dynamic about the behavior. When the
application state hits the client side, the flow of control is dictated by
earlier events or actions. Your application isn't likely to make decisions on
the fly about whether the current flow is concerned with creating an entity
versus deleting an entity. For example, the user and the application state
"know" already what is valid for an entity and it is likely that your
application is reflecting that in a hard-coded "action=[add|update|delete]"
parameter. Why funnel this state through a single method with a switch-
statement on the server side?

Incidentally, there are some references to caching the results of a POST
request[3] but I can't think of an production example that I've run across. It
might be cacheable if the response is a redirect to the same "list of
entities" URL rather than a direct URL to the newly created entity which is
arguably more RESTful but not cacheable.

[1] [http://restcookbook.com/HTTP%20Methods/put-vs-
post/](http://restcookbook.com/HTTP%20Methods/put-vs-post/) [2]
[https://webmachine.github.io/images/http-headers-
status-v3.p...](https://webmachine.github.io/images/http-headers-
status-v3.png) [3] [http://programmers.stackexchange.com/questions/114156/why-
ar...](http://programmers.stackexchange.com/questions/114156/why-are-there-
are-no-put-and-delete-methods-on-html-forms)

------
seivan
Good article, summarise what I like and don't like.

I wish it would delve deeper into versioning with some code samples. The way
I've done it in the past is just inherit from a controller and just override
an action as well as the json-builder. But that because unmaintainable after
version 3 or so.

I like how Relay/GraphQL sorta abstracts that away, but Ive had a hard time
figuring out how to make that work with the ORM (Active Record) so abandoned
for now.

~~~
TheEdonian
I know, this is just an introductory article. You can always take a look at
this great book for more info: [https://leanpub.com/build-apis-you-wont-
hate](https://leanpub.com/build-apis-you-wont-hate)

------
christogreeff
Nice read.

Sidenote: Should credit not be given for the use of the xkcd comic?

~~~
TheEdonian
You are totally right. Fixed it.

------
miseg
The elephant in the room for me is that while HATEOAS is mentioned, the
impression I get from posts from developers online is that people program
against a pre-agreed API format.

That's different to REST's automated discoverability for REST API clients.

~~~
spdionis
In my experience for most REST APIs use cases HATEOAS is not needed or not
that useful. Writing a REST API for your mobile application? What do you need
HATEOAS for? Do you really think it can replace documentation?

On the other hand all the rest of nice bonuses of REST APIs are very useful in
such a use case.

~~~
miseg
Exactly, that's where most implementations seem to decide against REST.

I agree with you. The other parts of REST (if you agree that REST can be
picked apart and still referred to as RESTful), as surely valuable.

------
Omnipresent
This is a great guide. Side note: Is there an example of implementing OAuth2
from API developers perspective and from API Consumers perspective? language
agnostic but Go or Java preferred.

~~~
TheEdonian
I haven't seen it myself, but I hear: Google I/O 2012 - OAuth 2.0 for Identity
and Data Access
([https://www.youtube.com/watch?v=YLHyeSuBspI](https://www.youtube.com/watch?v=YLHyeSuBspI))
is a great talk.

------
sinzone
No mention of swagger?

~~~
hannesvdvreken
Can't mention everything, right?

------
PierreLechelle
Great into on API development. Thanks for sharing :)

~~~
TheEdonian
Thanks for reading ;)

~~~
kbaijnath
I really enjoyed the article as well. I wasn't even aware of some of the
structure standards you listed (specifically JSend and HAL).

Side note: I think there is a typo near the bottom trough should be through in
the header based versioning section.

