Self-documenting API

A 3D render of a microchip with the letters API across its top surface.

Over the years I have worked on multiple APIs and created a few myself. Even though I have created several APIs I’ve only solely created one “large” API. Large is down to the reader and your specific experience. APIs which have a dozen or so endpoints can easily be documented in the project README. As soon as you have over 150 endpoints you need a plan, you need real documentation and a self-documenting API.

Definition

What is the definition of a self-documenting API? I have no idea what the official definition of the term is, below I’ve listed my requirements. If I’m way off base here, awesome! Let me know how I’m wrong, you can reach me on Twitter and via email.

Route list

When a developer makes a call to the entry point of your API, the response should document the features. That initial response should include a list of all the routes and the endpoints supported by the API.

We should all read the official documentation for tools we use but as we all know, documentation can easily become stale. If the API lists all the routes and endpoints the user will immediately know where to start looking for what they want.

Version, README and CHANGELOG

In addition to listing the routes and endpoints, the entry point for the API should list the version and include links to the README and CHANGELOG. Bonus points go to the developers who include a changelog endpoint within their API.

OPTIONS

The first two points are nice to have, however, they don’t make an API self-documenting.

Every route should support returning an OPTIONS response. The OPTIONS response needs to provide details (documentation) for the route, The response should list the supported endpoints, the fields and parameters required for each endpoint as well as a general overview of the route.

To see a working example, please make an OPTIONS request to https://api.costs-to-expect.com/v3/resource-types.

The response details the supported endpoints (verbs). The POST section details the fields which can be posted, the data type, validation rules and allowable values for linked data. The GET section details the supported query parameters and the supported sort, filter, and search fields.

Every route of the Costs to Expect API supporting returning an OPTIONS response; they are equally detailed.

Docs?

Yes, the Costs to Expect API still has documention, as great as OPTIONS responses are, you need to provide more detail sometimes. The Costs to Expect API documention lives on Postman and is in the progress of being moved to a GitHub repo.

Regardless of the size/complexity of your API, you need documention.

The longer your API lives the more important the documentation becomes We all forget the specifics after a long enough period, having an API which documents itself pays dividends down the line.

My development plan

Man starting a development process which ideally is back up by a development plan

In this blog post I discuss my development plan for Budget and Budget Pro. I also point out the pros and cons for each option I could take.

Why two individual apps?

From the start I always planned on their being two versions of our Budgeting App, Budget and Budget Pro. The relevant questions are: How will be achieved? What development plan makes the most sense?

A little background first

Budget is a free and open-source budgeting App powered by the Costs to Expect API. Budget Pro is the commercial offering aimed at users with more complex budgeting requirements and later, Businesses.

Now, The Options

There are three ways to end up with two related Apps.

  1. Start with the simpler App, duplicate, and add features.
  2. Start with the more complex App, duplicate, and remove features
  3. Build two independent apps

There are pros and cons for each option. A major pro for the first two options is they share a code base. This can also be a negative from a security point of view. We aren’t discussing that in this blog post.

Why not duplicate and add features?

My major problem with developing this way is the assumption you are only adding features. If you simpler and more complex version are only different due to a couple of features, this can work. However, when those features become architectural, the flaws to this approach soon become apparent.

Budget is a single user App and there is only one budget. Whereas in Budget Pro, there can be multiple budgets and budgets can be shared among users. These are core architectural differences. I could hack the budget service and add a wrapper for sharing, multi-currency, and multiple budgets but everything quickly starts to breakdown.

Why not duplicate and remove features?

This option is cheap, the simpler version of the App is clearly the ‘real’ version with code removed, it doesn’t sit well with me and is not something I would ever be comfortable doing.

Why two Apps?

As discussed above, the architecture for Budget and Budget Pro is different. Budget Pro will be multiuser, support multiple currencies and support multiple budgets in addition to many other features.

The budget “service” in Budget works well but it was designed knowing the requirements. At the time of writing Budget, we were still deciding what Budget Pro would include. We can add features to the “service” but I tend to find that adding features after often results in your well-designed service starting to feel a little hacky.

When you add on that one App is open source and the other won’t be, it starts to become obvious which development plan makes more sense, especially when you discount the first two :).

Any Benefits?

So, are there any benefits to writing two Apps rather than one? Well, yes, yes there are, I’m glad you asked.

There are three major benefits, speed of release, improved architecture, and the ability to learn from mistakes.

Speed of release

The simpler App will be the quickest to build, as such you can get something to market sooner. Yes, this benefit is shared with Option 1. You are always going to end up with architecture issues and feel the urge to strip out the code for the simpler App when the more complex version has been written and had the architecture fixed.

Improved Architecture

Each App will have been designed knowing what it needs to do. In theory, you will end up with the best architecture for each App. This is not a given of course, none of us are perfect but you are much more likely to get there following the development plan I am for Budget and Budget Pro.

Learn from mistakes

This is a newly discovered benefit, not something I originally considered. During the beta of Budget, we learned a lot from our first users, building two Apps means we can make use of those learnings and ideally not have to deal with them the second time and more importantly, release a much higher quality App.

Any Negatives?

So, what are the negatives, well, for one, there are two distinct code bases and two, the time required – it will take longer to write two independent Apps than building one and a half*.

Two code bases

It will always be harder to maintain two code bases, rather than one code base and a few extra features. There is no way around that point, however, it is a negative I am comfortable with as it allows me to try different things. Budget uses Bootstrap, Budget pro uses Tailwind, I would have been less likely to try Tailwind if the two Apps shared a code base.

Is the development plan working?

I think so yes, I’m still early in the development of Budget Pro but I’m enjoying the freedom. When I’m working on Budget Pro, I don’t need to worry about any of the baggage in Budget (it will get its own) and am free to design my new systems. I don’t have to worry about adapting or changing how something works and the unintended issues that come with that.

I’ll be able to give a more complete answer when I release the beta of Budget Pro. However, I’ve enough experience to know that I’m making the right choice.

* There is a possibility that this is not entirely true, if you opted for Option2, it is possible you will take so long to build the fully featured version you never get to release and therefore never get to the cut down version.