Design-first approach to building APIs

Filip Lackovic
Undabot
Published in
5 min readDec 4, 2019

Let’s kick-start this post with a common development scenario — you have 2 dev teams working on a project:

  • Backend
  • Mobile (iOS and Android)

A client needs feature X. Teams, with the PM and BA, agree on feature definition, scope and user stories.

Backend starts to work on API while Mobile is idle or focused on other tasks that can be done simultaneously.

As the backend team is developing, they are changing and rearranging things along the way to fit existing codebase, often resulting in a not so good developer experience for the API consumers (in our case — mobile team).
Once the API is ready, Mobile can start working on their integration part. At some point, they will notice issues with API design or even integration incompatibilities and will request a change.

This can occur more than once in a feature development life cycle and every time it will push back development as backend must be switched back to this task, while mobile is waiting for backend to make changes, etc.

This process is far from optimal — lots of man-hours can be spent on integration and design issues which will result in a slow development process, communication overhead between the backend and the mobile teams, longer sprints and finally — a costly feature for a client.

By investing more time in planning, discovery and design, we can streamline, optimize and parallelize development while improving DX for API consumers.

Let’s apply this idea to the scenario from the beginning of the post.

A client needs feature X. Teams, with the PM and BA, agree on its definition, scope and user stories. BA, Backend and Mobile pull together in a meeting and spend as much time as necessary for everybody to understand a feature from User stories and edge cases to integration points between applications. The result of this meeting must be some sort of documentation in the form of an API description language that will serve as a contract between the backend and the mobile team against whom the mobile can integrate.

With a documented API, backend and mobile can both start working on their parts simultaneously. Since everything is known and documented, there is little to no communication needed between the teams, no idle time, blockers or distractions. Sure, there will be times when the team will discover an issue with the API design and that is OK. The team should meet again, discuss the needed changes and update the documentation. Release management should be applied, meaning that the updated documentation should be released, according to the semver (e.g. v2.0.0) with proper changelog describing the reason for the new design.

Your future self will be grateful for investing a few minutes in describing your discovery! When all sides are done with their part, the only thing that’s left is the actual integration, which is, if everything is done according to the API specification, seamless.

There are several key benefits with later approach:

1. Common baseline

By designing the API together, any potential changes in the later phases are trivial to communicate, as all members share commonly agreed upon baseline and are aware of other team’s limitations and needs.

2. Teams can work simultaneously

Given that there is a specification that’s agreed upon and available for everyone to see, teams can work simultaneously without dependencies on each other or even generate their own mock server to test the integration or have control over the data they are receiving. Also, the mock API can be generated and provided by the backend team at a fraction of the time needed to develop a fully functional API which allows other parties in the process to start working completely asynchronously.

3. Early feedback and problem identification

Design & discovery phases usually yield a new knowledge about the domain, edge cases, flaws and potential problems. That’s very valuable — especially this early in the process.

Also, the backend team will get an early feedback from the API consumers, before a single line of code is written — eliminating potential pushbacks at the later phases, which can cost money and disrupt the development timeline, team loads and deadline.

4. Good Developer Experience

By designing first — we are thinking from the outside — in, specifying the API as it should look, not thinking about potential implementation limitations. This can, in turn, require some refactoring if the existing codebase does not fit — which is an additional benefit in itself.
We can draw a parallel with testing. Non-testable code is an indicator of bad architecture.
Code that does not fit the proposed API design is an indicator of bad implementation.

5. Documentation artefact

Writing documentation and keeping it up to date is always a sore point. Design-first approach eliminates this, as no development can be done without it, so having no documentation is impossible :)

6. API client generators

There are plenty of tools for generating clients from the API specification (for example https://swagger.io/tools/swagger-codegen), which can speed up the development and reduce the time spent writing boilerplate code. Also, this generated clients can be used as a part of the CI process for automatic testing of the API.

7. No silent changes

The specification must be versioned, ideally following semver so there are no silent changes that will break consumers’ implementations.

8. Following standards

By using one of the common standards for designing and describing the API, consumers can know upfront how to interact with it, or even create premade plug-and-play implementations. One great example of this would be CMS which, if following the same standard as the API, can be implemented with little to no effort.

Documentation is always a sore point for developers, mostly because it comes only after the feature is done, and at that moment the focus is completely switched to the next one or the budget is already spent and there is no time for documenting what has been done. The same goes with tests, so one of the benefits of Test Driven Development is that it leaves the tests as a side product. Again, drawing parallel with tests, we can call this Documentation Driven Development 😀

By making it first and required step in the process, we can assure that there will always be, at least as a side effect, an up-to-date document describing the behaviour of our application API and making life easier for our future selves or colleagues.

Tools and references

Thanks to Antonija Butković for the design!

Thank you for reading. Please comment, like or share it with your friends and we hope to see you soon.

Would you like to join us? Check out the open positions at our Careers page.

--

--

Filip Lackovic
Undabot
Writer for

Software engineer, InfoSec enthusiast, problem solver