7

Most API libraries define one method for each endpoint. If there is an endpoint for getting user information, you might have a method like:

getUserInfo(userId);

That simple method is often a wrapper around another function that actually does the api call:

apiCall('/user/info', {userId: userId});

Another option I see less frequently is for the library to only contain the method that makes the API call.

The first method only has the advantages of code discoverability, but it isn't that big of an issue for dynamic languages. Some say it also removes the need for the developer to read documentation for the APIs, but why would you ever want somebody using APIs without reading the documentation?

The second method has three advantages that I see:

  • The library is dramatically smaller
  • Methods don't need to be updated if the API ever changes
  • There is no need to maintain documentation for the library; the API documentation fulfills that purpose

But I don't see the second method used very often, so perhaps I'm missing something. When is it appropriate or inappropriate to use either method of writing API libraries?

1
  • If getUserInfo just passes its parameters through to the apiCall, then there is little sense in having it. As soon as getUserInfo is part of a larger class that hides away setting up memory structures, handling state, or other such awkwardness, then it is very much wanted. It would then be analogous of any IDE's library that deals with the OS's widgets for the GUI. I know that using Delphi I certainly do use the Windows API frequently without reading its documentation because the Delphi VCL and RTL hide it nicely for me. I only delve into the API when I need to code an API call my self. Commented Aug 2, 2012 at 6:05

2 Answers 2

6

I would always vote for the getUserInfo(userId) style methods to be included, for these reasons:

  • discoverability;
  • less written documentation needed (as the methods, their context, their names and their parameters document themselves mostly);
  • methods describe available functionality;
  • library may not be significanltly smaller as these methods are themselves really small;
  • hiding details such as JSON <-> Object conversions and error handling;
  • save different users from having to write similar code to use the API;
  • if the API changes, only the library has to change. Otherwise, all code ever written for the API has to change.

Furthermore, with such methods you get the ability to:

  • validate arguments before sending the query;
  • do custom formatting on input arguments and custom parsing on return values, invisible to the library user;
  • put the methods in logical classes and namespaces: cleaner API;
  • use and return custom objects that encapsulate data commonly found together (such as a User or BlogPost objects);
  • include workarounds for bugs or provide a logical/consistent API view of an illogical/inconsistent API (design);
  • convert error return values into exceptions.
0

getUserInfo(userId) looks like a simple local function call. You don't care if it's doing any REST or SOAP connection to retrieve the user, or if's retrieved from a database. At this level of abstraction it may be valuable to do so; when you're dealing with business rules involving users, you are not necessarily interested about the details of how this data is retrieved. Also by designing your code this way you have the possibility of changing these details (e.g. modifying the REST interface) without changing all the code that calls this function.