Implicit vs. explicit APIs

Published on and tagged with design  software engineering

When developing an API, one point you have to consider is whether you want to provide an implicit or an explicit API.

An explicit API is usually quite self-explanatory, the method name tells you what the method does (at least, if it has a good name). Some examples from the core of CakePHP:

Model::findAll($conditions = null, $fields = null, $order = null, $limit = null, $page = 1, $recursive = null)  // deprecated
Model::findCount($conditions = null, $recursive = 0)  // deprecated
FormHelper::checkbox($fieldName, $options = array())
FormHelper::submit($caption = null, $options = array())

On the other hand, an implicit API doesn’t tell you what the method does (respectively it does it on a more abstract level):

Model::find($type, $options = array())  // new syntax
FormHelper::input($fieldName, $options = array())

In the first example, the $type parameter determines what the method does, and in the second example it depends either on the data type of the respective database field or on the value of the “type” option.

For you as a developer, implementing an implicit API means a) you have to write more code and b) you have to write more documentation (because you also have to explain what the method does)… On the other hand, an implicit API allows you to provide a unified API (e.g. Model::find(‘all’), Model::find(‘count’), and Model::find(‘list’) vs. Model::findAll(), Model::findCount(), and Model::generateList()).

For a user, an implicit API is probably more difficult to use than an explicit API, at least in the beginning. For example, if you want to get the number of some records, you first look for a method with “count” in its name. With an explicit API you will find the Model::findCount() method, but with an implicit API you probably won’t discover that Model::find() supports a “count” type…

Anyway, in the end it is up to you to decide which approach better fits to your specific situation. Both approaches have their advantages and disadvantages.

7 comments baked

  • James

    Hi, I’ve just started using 1.2 and I had to hunt down the find() method in the API and look at the code to see what other functionality it has.

    It makes sense to use just the one method and once the documentation is more extensive it will make it easier for people to see how and why the method behaves the way it does.

  • leveille

    Excellent breakdown of the differences between the two. I find myself favoring an explicit API, however that is likely because I spend most a lot my time creating/exposing web services. Though I suppose a RESTful resource request which allows the inclusion of actions would be considered implicit:

    GET /articles;recent (implicit)
    GET /articles;popular (implicit)
    GET /articles;archived (implicit)
    GET /articles (explicit)

  • Abhimanyu

    Hey, is this the new syntax ?
    Model::find($type, $options = array()) // new syntax

  • AndyB

    IMHO Implicit API’s are only practicable, if the $options-array is well documented or even better: an object like in Java. If you can’t reuse your $options-array for several formerly explicit API’s, there is neither less documentation to write nor less code.
    For the examples you brought up, it makes sense to use implicit API’s, but again: $options has to be well documented!

  • Anonymous

    just skip this array abuse nonsense and get keyword arguments in python/django

  • Abi

    Thanks for the excellent overview of the two types of APIs. As a programmer, I seem to prefer an implicit API because it feels much more elegant. However, when I first started using cakephp, I found the implicit find() pretty irritating and troublesome to get started. So, as a user, I prefer an explicit API. Ironic…

  • cakebaker

    @all: Thanks for your comments!

    @James: Yes, reading the source is a good way to learn what the code does. On the other hand it is a bad smell, if you have to read the code before you can use it… But as you said, this situation will hopefully become better with more documentation.

    @Abhimanyu: Yes, that’s how the new find method looks like, at least in principle. In practice, the method signature is still the old one (for compatibility reasons):

    find($conditions = null, $fields = array(), $order = null, $recursive = null)

    @AndyB: Yes, the $options array has to be well documented, or else you have to dig into the code to figure out how it must look like.

    @Anonymous: Hm, as far as I know, PHP doesn’t support keyword arguments, so you have to use an associative array to (partially) simulate keyword arguments.

© daniel hofstetter. Licensed under a Creative Commons License