1. 54
  1.  

  2. 16

    Looks like a few people have a hard time wrapping their head around the fact humans need to still interact with APIs in order to learn about behaviors of it (via cURL or similar).

    100% agree with the article. Well said.

    Edit: To further this point, look at all the projects which have popped up which literally give a UI to APIs to test them quickly, i.e. Swagger. This is the API literally manifesting into a user interface. Might want to mention this in the article.

    1. 8

      I didn’t really have REST APIs in mind when writing this, but more library APIs: libX11, libpng, that kind of stuff, but also larger things like Ruby on Rails (good UX is a major factor for Rails’ success). Of course, it applies to REST APIs as well, but a number of people seem to take “API” to be short for “REST API” these days, but that’s just a tiny fraction of all APIs most people work with.

      1. 1

        I would say the same applies - libXXX usually manifests in a command line interface or GUI (ffmpeg is a good example of it manifesting in both).

        Yeah, API is pretty much synonymous with REST API these days, agreed. While I believe it’s much more broad than most people think, we have to use language which the general public is familiar with (not critiquing you, just a general statement).

    2. 6

      The “Example Driven Development” technique described is similar to Readme Driven Development.

      1. 1

        Interesting, my kinda-popular library has a really extensive README, because I think it’s really important to give people a good overview of what the library does and does not, what the design principles are and what’s the rationale behind certain decisions.

        Still, I stopped counting the number of people suggesting/demanding I add their special config option who have very clearly not read the design goals section of the README.

        Only thing worse are the people who fork the library, change things around (usually because they haven’t spent the necessary time thinking about what their change actually means), add a “2” to the original name, and publish it without updating the README.

      2. 4

        Well, of course. That’s the only reason libraries like “Request” (Python) had huge sucess. Requests does the same than regular http-handling Python code, but with a friendlier API.

        An API is a user interface for the programmers that use it.

        1. 4

          Well, of course.

          You say that, yet the majority of software, open source libraries and otherwise, does not follow this advice, simple and effective as it is.

        2. 3

          I’m strongly of the opinion that programmers should more often think about this the other way around – treat user interfaces like APIs. The user is a very important part of a functioning system; UI breakage implies system breakage. When you make backwards-incompatible changes to your UI, you’ve broken the system until the client (user) adapts to the new interface. When you introduce focus-stealing, asynchronously-appearing modal dialogs, you’ve added a race condition.

          Command-line tools provide an interesting in-between point, because they’re usually built to be usable by both humans (users typing shell commands) and machines (scripts invoking the same tools). The latter in particular tends to discourage backwards-incompatible behavior changes, though I for one very much appreciate the UI stability for usage from meatspace as well.

          1. 2

            I totally agree with the article. I also had similar thoughts before. l‘m now a firm believer that Python is just a really good API and not really a programming language*. Its just so good at building good APIs and there are so many Python projects out there which have an amazing API.

            *It‘s obviously not true, but I sometimes like to think this way.

            1. 2

              Yes. There’s nothing worse than providing some sort of API and not having any (internal) consumers for it, so you won’t notice and breakage or nobody has any clue how to use them. Bonus points for generated bindings in languages you don’t really use :P

              1. 2

                Don’t really agree with the title. The core logic of a program can (optionally) interact with humans and/or other systems. With neither, one is left with a “run to completion” program that typically transforms its OS supplied inputs into outputs.

                A “user interface” is associated with human interaction, whereas an API is associated with interaction with other systems. That human interaction is in terms of the user of the program, not the producer.

                That programmers are human, might mean that they need to program against an API, but surely that doesn’t mean that the term “user interface” should be extended to it?

                1. 4

                  That programmers are human, might mean that they need to program against an API, but surely that doesn’t mean that the term “user interface” should be extended to it?

                  I suppose you could argue if it’s the best term, but to me it seems that there are two layers: implementation and exposed API. The implementation is all about doing “stuff” and interacting with the computer, whereas the exposed API is about giving the user access to this in a reasonably convenient way.

                  The API part very much seems like a “user interface” to me, with some good and bad ways of doing things, starting with everyone’s favourite bikeshed of naming things, but also deciding things like if you want one function which accepts 5 parameters, or 5 functions which accept one each. It’s really hard to say something general about this, since it depends on what those parameters are, environment conventions/possibilities, etc. but those kind of decisions don’t really matter to “the program” or “the computer”, but can very much matter for the humans dealing with all of it.

                  1. 2

                    Another way to look at it is from the perspective of internal DSLs. Martin Fowler, for example, wrote that

                    an internal DSL is nothing more than a quirky API (as the old Bell labs saying goes, “Library design is language design”).

                    When viewing the API as a language it is probably more obvious that it is made for humans.

                  2. 3

                    API’s are how programmers (indirectly) interact with a library. After all, most of the code is written by humans, and is therefore interacted with by humans. API’s are the way humans interact with foreign code, albeit seemingly indirectly due to the apparent interaction being automated. But the thing about automation is, somebody had to setup it, and that somebody needs to interact with both parts to do it. That somebody is usually a programmer, and he usually interacts with an API’s to combine the parts.

                    1. 2

                      Not really: API documentation is how programmers interact (directly) to discover a service.
                      They use it to hardcode an agent that will interact (directly) with the service resources.

                      Unless the API is using “in-band” documentation, there is no reason for a programmer to use it except to make some manual tests.

                      1. 4

                        How do you instantiate objects or call methods or functions in an API using only the documentation of the API and not the API itself? When I write software, I use the APIs of all of the libraries that I use. If those APIs are well designed, then I don’t need to consult the documentation very often because they use the same abstractions everywhere, consistent naming, and so on. None of this matters to the program as it runs, all of it matters to me as I write the program.

                        1. 1

                          I would argue that the action of “hardcoding” is the interaction with the service. But this very much relies on how do you define interaction. Does manipulating dangerous substances with a manipulator arm that you control is an interaction? What about a stick? What about gloves? I’d argue that as long as you control how something interacts with something else you as well interact with it.

                          1. 1

                            You are not the program you’re running.

                            1. 5

                              I’m also not the stick that I’m using to poke a bear. But I think most people would say that I’m interacting with the bear - even if through a proxy. In API’s case, the program is my stick, and API is the bear.

                              1. 1

                                You seem to like analogies :) But I’m not sure it’s a good idea to convey the subtleties of abstract concepts and vocabulary that are already conflated and misunderstood by many.
                                If the program was your stick, then you’d have to be there at all times for it to function. Is that so? Are you the actor that makes your program run? No. You’re the programmer that used the documentation of the API to create an agent of that API.

                                In bear terms, you’re the guy who created the stick and the creature that’s holding it, and this creature with its stick is the one interacting with the bear, not you.

                                But I guess we’re arguing about meaning and definitions, and I get what you’re saying, but I’m still wondering why no one wants to differentiate those 2 very important parts of API interactions: documentation and usage.
                                It seems like everyone agrees it’s the same thing?

                    2. 1

                      As much as I like discussions about APIs and the idea behind “Readme Driven Design”, this article seems to confuse API documentation with API usage.

                      Indeed, programmers consume API documentation, but the main (by large!) users of an API are the agents (e.g: a browser/hypermedia agent, or even an hardcoded agent, unfortunately).

                      The failure of implementing correct hypermedia APIs is what drive us to think that programmers are the users of an API, and make us complain that the docs are clunky.

                      Even the name (Application Programming Interface) should totally discourage the author to write such a title: APIs are interfaces between programs, not programmers/users.

                      1. 10

                        APIs are interfaces between programs, not programmers/users.

                        It seems to me that it’s the user (programmer) who is using it. This seems a bit like saying that hammers need to be user-friendly just for nails, and not the person using the hammer.

                        1. 9

                          If I go through and change every function, method, and type, and variable name in my API to A followed by the number in which it appears, it will generate almost identical binary code when it is compiled, yet it will be almost impossible for anyone to actually write a program that uses my library (even if I document it well). Good API design is therefore a human-computer interaction problem: how do I name things consistently, pick reuseable abstractions, and so on such that the affordances of my library allow humans to write bug-free programs that consume my library?

                          1. 3

                            This is certainly an interesting conversation and of course open to subjective opinions.

                            I’m not sure that the distinction between documentation and usage helps much here.

                            As a thought experiment, how about a parallel context - shells and shell scripting. I use programs like grep, awk, and so on, directly, as a human. I also write shell scripts that use those same programs. The shell scripts are the agents. But that doesn’t take away the usage I’ve experiences of those programs as a human; it doesn’t reduce the “user interface” requirements or relevance.

                            I discover what a system can do by playing with the API, using it directly. I may also refer to documentation. The title of the post, for me, is valid.