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 Git Workflow

Pipes and nodes to replicate a git workflow of multiple branches merging into each other

I haven’t written about my Git workflow for over a decade. The last time I documented my Git workflow was during a contract. I needed to explain Git to a new employee who was new to development.

My perspective

I’m writing this post based on my experience as a solo developer. Unless I am in a contract, I spend much of my time working solo. There is no reason these workflows won’t work with small or larger teams; your results will vary. With larger teams you don’t get a choice though as the organization decides what is best.

Project Type

The type and state of the project maters. When the project is in the initial stages of development and there hasn’t been a release, everything happens in “main”. A release could be the first alpha release for testers, the initial preview for a client or just the point that feels right. If the project is past its first release, the only question that matters is, public or private repo?

If the project lives in a public repository, all my development happens on a fork. The fork is effectively my feature/dev branch. I will merge back into “main” as often as possible. I will merge when a specific feature is complete, when a bug is fixed or just when it feels right. My work on Budget is an example of this, I have a fork and never commit directly into the “main” repo.

When the project lives in a private repository, all my development happens on feature branches. Where possible these are small feature branches. We all know that sometimes you are going to have the long-lived feature branches, in those instances I will merge main into the long-lived feature branch anytime “main” changes. Budget Pro lives in a private repository so there is no fork, just the main repository.

Feature branches

Whenever possible, yes, small feature branches are the way to go. The only real change in my approach is where the feature branch lives, is it a fork or a branch off “main”.

There are exceptions, there will always be edge cases. Edge cases are different for all of us, you know yours. If your edge cases are rare, it is ok to break the rules occasionally.

If you got to the end of this post and are wondering, well, that seem simple, yes, that is the point. Our work is hard enough, we don’t need to complicate it by adding unnecessary steps to our development processes.

I have avoided talking about continuous integration and continuous delivery in this post, they are topics for a different day. Our first priorities should be making development easy and ensuring “main” is stable.

This post is a continuation of a series in which I talk about me development process. Please check out some of my other posts, my typical project setup and action class usage in my Laravel apps.