
API Design is UI for Developers - mmahemoff
http://shkspr.mobi/blog/index.php/2012/03/api-design-is-ui-for-developers/#comment-15885
======
masklinn
The sentiment in the article looks laudable at first glance, but I have _real_
trouble when the first paragraph ends with this:

> In many ways, PHP is that programming language. It’s simple, logical

and does not follow with "just kidding". Especially when the article itself
contains things like:

> Keep your parameters consistent.

or

> What’s easier to remember “gnxID” or “getNextId”?

or

> Consistency is a virtue. If you have two similar APIs (say, search & read)
> they should take the same parameters and produce identically formatted
> responses.

Furthermore, while many of TFA's demands are the "well... duh" kind (though
they do bear repeating), quite a few are also highly debatable:

> Just because you love Ruby, doesn’t mean everyone does. Show examples in a
> variety of languages.

Not sure why, as long as the examples are clear and readable (meaning Java is
probably out as the only demo language), the language used for the examples
should not matter. Stripe is awesome[0] but I don't think that thing should be
termed as a requirement, let alone a "basic requirement".

> * Yes, you love XML. Guess what? I don’t!

> * The customer is always right. If the customer (developer) wants JSON, XML,
> PHPobject, or just plain text – you should give it to them.

> * It’s the API designer’s job to make life easy for developers – so reply in
> whatever formats the developer wants.

Is a second — significantly worse — iteration of the one above (and
nonsensical in the face of the latter demand that the API developer provides
libraries in a variety of languages: why do you care what the response format
is if it's all hidden behind an access library exactly?). Are multiple
response formats awesome? Sure. Are they a requirement? Fuck no, developers
are not babies, as long as they have tools which let them process your
responses (meaning ASN.1 is probably the wrong response format in most cases)
they'll handle it just fine.

> The Wikipedia API is a brilliant example of this. They have a human readable
> response for their API calls.

The link leads to a dump of the XML response in an HTML page [1] in which
lines are not wrapped and the non-text content of the response is a uniform
and unreadable shade of blue. Meanwhile in every browser released in the last
15 years the original XML response [2] has syntax coloration, nicely wrapped
lines and the ability to fold sub-trees you don't care about.

If [1] is brilliant, I'll do without brilliance thank you very much.

TFA's demands/recommendations are to be taken with a significant grain of
salt: there's good, there's bad, and you'll have to pick them apart on your
own.

While it does only cover documentary issues (which really are 30~50% of TFA)
and not API design, I'd strongly recommend reading Parse's "Designing Great
API Docs" instead[3], I find it comes across far better and... it documents
what it preaches via examples for almost all its "bullet points".

[0] <https://stripe.com/docs/api?lang=curl#top>

[1]
[http://en.wikipedia.org/w/api.php?action=query&prop=lang...](http://en.wikipedia.org/w/api.php?action=query&prop=langlinks&lllimit=200&llurl&titles=API&redirects=)

[2]
[http://en.wikipedia.org/w/api.php?action=query&prop=lang...](http://en.wikipedia.org/w/api.php?action=query&prop=langlinks&lllimit=200&llurl&titles=API&redirects=&format=xml)

[3] <http://blog.parse.com/2012/01/11/designing-great-api-docs/>

~~~
edent
I'm the author - please allow me to clarify.

1) These are some hastily tossed off thoughts on a Sunday afternoon; not a
manifesto. Quite happy to be taken to task on any of the points.

2) PHP is a perfect beginner language. Having tried everything from C, ASM,
Java, Prolog, Java etc - I'd much rather play around in PHP. Ruby is similar -
it's a well designed language with fairly little cruft - but I've limited
experience in it.

3) As I say - most should be obvious. Yet most APIs aren't well designed.

4) Primarily, I'm looking at this from the POV of someone who spends a lot of
time at hackdays. Yes, if you've got a week to learn the API, it doesn't
really matter how your provide the API. But if you want people to get started
quickly, provide as many languages and good libraries as possible.

5) You're probably right about the Wikipedia example. I think Apigee provides
a nicer way of looking at a response.

Thanks for the link to Parse - looks interesting.

To reiterate - these aren't designed as a concrete example of best practice,
just a way of looking at the problem which I don't think many people have
considered.

Thanks for the comment - I may update the piece to reflect some of your very
fair criticisms.

T

~~~
aDemoUzer
Try python - it would blow your mind. For 7 years, I too was a PHP believer
for its simplicity. It was my favorite language by far. 1.2 year ago, I
started to use python and was hesitant with it at first. As I worked more and
more in python, I simply fell in love it. It does lot of greats things that
PHP does (dynamic arrays, dictionaries, and functional programming) and adds
lot more functionality that PHP is missing.

1\. How would you add a new element to an array? PHP: array[] = 2 Python:
array += [2]

2\. How to combine 2 arrays? PHP: ?? array_merge(...) ?? Python: array +=
array <\- it is as simple as appending to a string.

Lot more fun examples:
[http://python.net/~goodger/projects/pycon/2007/idiomatic/han...](http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#swap-
values)

------
philbo
I'm building a public API in my current job and, a few weeks ago, I was
scouting around for the good API design advice. Absolutely far and away the
best resource that I found was this Google TechTalk by Joshua Bloch:

<http://www.youtube.com/watch?v=aAb7hSCtvGw>

If you're interested in the topic and haven't seen it yet, I urge you to do so
ASAP.

~~~
tomgallard
Building the API for Pwinty (<http://www.pwinty.com>) I found the Dropbox API
docs to be a really good example of how to structure your documentation -
<http://www.dropbox.com/developers/reference/api>

All the resources are documented in the same way, it is nicely formatted, and
easy to understand.

~~~
masklinn
Parse's blog has a pretty good article on documenting APIs[0], with links to a
number of nicely one API documentations (not dropbox's, but Github's,
Stripe's, Backbone's, Mailgun's and their own)

[0] <http://blog.parse.com/2012/01/11/designing-great-api-docs/>

------
adelevie
I've started a small experiment in self-documenting REST APIs.

It's a quick and dirty Ruby gem that exposes CSV data with RESTful endpoints
(read-only for now) with a pretty docs page that automagically gives you:

1\. Example code

2\. Documentation for every single function

3\. Human readable requests/responses

Automatic generation of client SDKs is a big TODO.

If you're still interested, check out <http://github.com/adelevie/restivus>.

~~~
masklinn
> I've started a small experiment in self-documenting REST APIs.

Reading your docs.erb, the core structure (of the docs, and of the APIs it
will document) seems to be along the lines of URL > Verbs > Content.

According to Fielding, you probably shouldn't call it REST or RESTful, because
it's not[0]:

> A REST API should spend almost all of its descriptive effort in defining the
> media type(s) used for representing resources and driving application state,
> or in defining extended relation names and/or hypertext-enabled mark-up for
> existing standard media types. _Any effort spent describing what methods to
> use on what URIs of interest should be entirely defined within the scope of
> the processing rules for a media type (and, in most cases, already defined
> by existing media types)_. [Failure here implies that out-of-band
> information is driving interaction instead of hypertext.]

and

> _A REST API must not define fixed resource names or hierarchies_ (an obvious
> coupling of client and server). Servers must have the freedom to control
> their own namespace. Instead, allow servers to instruct clients on how to
> construct appropriate URIs, such as is done in HTML forms and URI templates,
> by defining those instructions within media types and link relations.
> [Failure here implies that clients are assuming a resource structure due to
> out-of band information, such as a domain-specific standard, which is the
> data-oriented equivalent to RPC's functional coupling].

That your documentation is function-driven:

> Documentation for every single function

also hints at this being RPC-over-HTTP more than REST (which is fine, as long
as it's called correctly).

[0] [http://roy.gbiv.com/untangled/2008/rest-apis-must-be-
hyperte...](http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-
driven)

~~~
adelevie
Hey masklinn, I'm totally receptive to constructive criticism like this, so
can you make it _even more_ constructive? :)

I've seen many "RESTful" APIs with this structure:

GET / => index

GET /<id> => show

GET /?someparams=someattrs => filtered index

POST / (with encoded params) => create

PUT /<id> (with encoded params) => update

DELETE /<id> => delete

If you made a Rails scaffold, and got rid of any of the POST, PUT, and DELETE
actions, and then added some basic filtering to GET "/", you would have a
nearly identical API as generated and documented by Restivus.

~~~
masklinn
> Hey masklinn, I'm totally receptive to constructive criticism like this, so
> can you make it even more constructive? :)

Sure, just ask, I'll answer if I can.

> I've seen many "RESTful" APIs with this structure:

Yes, and that API is not even remotely RESTful according to Fielding (whom you
may or may not agree with, but he's the guy who thought up REST and coined the
acronym). It can be a fine API, but not RESTful: it's not hypertext-driven,
instead it's a (hierarchically organized) set of function calls mapped onto
HTTP.

~~~
adelevie
Between your edits and this reply, there's a lot to chew on, but I'll focus on
one point which leaves me dumbfounded:

> also hints at this being RPC-over-HTTP more than REST (which is fine, as
> long as it's called correctly).

In any context, documenting every function is good practice.

~~~
masklinn
> In any context, documenting every function is good practice.

If your API is procedural (is RPC), then yes, procedures being your core
abstractions that's what you document.

But REST is not procedural, the core RESTful abstraction is the resource and
it is that resource which provides state transitions from itself (to itself or
to other resources). In HTTP these transitions are a triplet of (method, URI[,
body]) but that's incidental.

Because the core abstraction of REST is the resource, resource types (or media
types) is what you document, and the possible transitions from a media type
are documented as part of that media type (more precisely, the media type's
documentation indicates what the transition hookpoints are — for instance in
HTML they're <link>, <a> and <form> — and what the semantics of those
hookpoints are relative to the resource — if any).

To clarify, I have absolutely no issue with your goal of documenting your API
and every endpoint of your API, I just take issue with your claim of
documenting RESTful APIs when the very structure of your tool and production
preclude any possibility of RESTfulness.

------
gdubs
Great sentiment. One thing that jumped out at me was "Don’t engage in a
needless dance where developers have to take several steps to do a single
action."

I think if you want to follow the "rule of least surprise" from the unix
school of thought, this is probably a somewhat dangerous suggestion. Having
one call go and do several things can make that call become something of a
black box. It kind of breaks the rule of transparency as well. If I find
myself having to do a dance with the API, as the end user there's nothing
stopping me from writing my own helper code to group those common calls
together; I'd prefer an API with total transparency and the least amount of
surprise, which is ultimately more flexible.

~~~
Someone
Even better, IMO, would be a layered API, with a lower layer of 'atom' (atomic
would be a good name, if it wasn't taken for something else already) calls tht
do one thing, and a clearly separate layer of 'molecule' calls that help you
perform common operations. For example, reading a text file into a string
would be a 'molecule' call. That call would not need to be as flexible as a
hand-coded open-read-convert bytes to characters- close chain. For example, it
could assume a UTF-8 encoding.

------
JVIDEL
I agree, except about C++, and PHP is kind of a mess, not what I would use as
an example of a simple and logical language.

------
georgieporgie
_When I first started learning C++ (back in the bad old days)_

Siiiigh. Here we go again, the C++ hate bandwagon. Let's see why he thinks
this.

 _I was convinced that any 1st year student could design a better programming
language._

That's normal for someone who doesn't yet have any idea what he's talking
about.

 _One which behaved in a sane fashion without a lot of legacy cruft._

Okay, that's kind of vague...

 _In many ways, PHP is that programming language._

Nope. No, it isn't. Not at all. PHP is a mishmash of C-ish APIs that get
things randomly backwards along with some handy built-in constructs. Also, it
has some of the most appalling documentation of any mainstream language.

 _works without having to know lots of esoteric computer science._

I would love to know what "esoteric computer science" necessary to use C++, or
any language for that matter. But that's not contained in this link-bait-y
post.

