Why You Should Be Designing APIs to Spec

There’s a good reason why building APIs can be extremely tough and time-consuming: they have to cater to both human and machine needs.

Inherently, this is pretty difficult. Machines are picky and rely on pure logic; they crave rigid, hierarchical structures and definite instructions. On the other hand, humans prefer things to work on an instinctual level — our brains cope well with filling in the blanks.

APIs are the direct interface between machine and developer, so designing them well means making compromises. They should be straightforward enough to make for easy serialization and minimal enough to decrease unnecessary overhead on useful payloads. It’s also handy when APIs are self-documenting, with clear error handling, along with other features to maximize user satisfaction.

Jason Harmon, Chief Platform Officer at Typeform, knows how to make these compromises. With his experience architecting microservices at PayPal, Braintree, and now Typeform, Jason suggests using an API specification as the backbone of your design process, highlighting a focus on human usability.

This post was inspired by a presentation from Jason Harmon. Watch his talk from the 2017 Nordic APIs Platform Summit below:

Putting Human Needs First

Catering to both human and machine needs isn’t easy, but Jason’s quite sure that humans make the better starting point. The reason being is that machines are predictable, and they can be programmed to work under a range of constraints – given the right instructions. Plus, they won’t take personally to tough negotiation in the same way your business folk and developers might!

But… how exactly do you build an API without putting the machine first?

Jason suggests you start out by writing a brief description of your API, outlining all the planned capabilities in customer language (which has a big overlap with business language). This is a bit like goal-setting for your API, and it plays that role too; not only will the plain-English description tell business folk what the API does, but it will also allow you (and everyone else) to decide whether or not the finished product meets expectations.

What now? We have a lovely description of our yet-to-be-created API, but it doesn’t answer any of the technical questions that both internal and external developers are asking.

Jason is certain that the next best step is to create a specification for your API, which you can use to both structure and flesh out your API without writing even a single line of code…

Creating an API Specification Is The Natural Next Step

Simply put, specs are documents you can use to define pretty much every aspect of your API. They’re mostly used to list your API’s many functions and commands, which you might note down with brief descriptions, sample Requests or Responses, and all your input/output parameters.

Typically, you’ll create specs to a standardized format of your choice, an example being the very popular OpenAPI specification – formerly known as the Swagger specification – for RESTful services. Admittedly, it gets a bit confusing here, because the word “specification” or “spec” refers to both the document itself and the format being used.

The OpenAPI spec is just one of many specification formats. You can read about a few more popular ones in our article on the subject here.

As the OpenAPI page describes, specs are designed to “effectively [map] all the resources and operations associated with [an API]”. Better yet, they do it in a format that’s “easy-to-learn, language agnostic, and both human and machine readable”. Just take a look at this YAML excerpt from OpenAPI’s Petstore spec:

   delete:
      description: deletes a single pet based on the ID supplied
      operationId: deletePet
      parameters:
        - name: id
          in: path
          description: ID of pet to delete
          required: true
          schema:
            type: integer
            format: int64
      responses:
        '204':
          description: pet deleted
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

It’s pretty easy for both humans and machines to understand that this portion of the spec is describing an operation called deletePet, which – just as the description key says it does – deletes a single pet based on the ID supplied. It also tells us that the operation’s only parameter is the pet’s id (even giving us a brief explanation of the parameter itself) and shows the two possible responses.

This kind of object notation should be somewhat familiar to most developers, so it’s hardly any trouble for them to pick up OpenAPI and create a spec pretty quickly.

Now, because specs follow a machine readable, standardized format (or at least they should, there’s no reason not to!), there are hundreds if not thousands of open-source tools that can draw from the spec you’ve already built to do clever things – like create all sorts of mocks and usage materials.

Since a specification already contains a clean, comprehensive overview of everything the API has to offer, it’s easy to package this information into, say, beautiful reference docs. You could use a tool like SwaggerUI for that, or – if you have a thing for three-panel designs – try ReDoc. This not only helps in easing an API release to the public, but acts as an immediate proof so that business folks can see tangible results nice and early.

Automated documentation is one of many such things your spec can help create. You might also generate server stubs to create the base for your server early-on, or create SDKs – like with APIMatic – to distribute to external developers upon release.

Now while your spec will never actually fetch any real data, it still gives a solid representation of what the finished API will be capable of, and how it will work. This means that straight off the bat, you can be recruiting all of your team members, and perhaps even a select few external developers, to collect early feedback. If any changes need to be made, well then it’s great you caught them early-on!

Only Build When Spec-Based Design is Exhausted

With this spec-first approach to designing your API, you might be wondering: when is it actually time to start building my API?

Jason Harman believes you should leave building the API until you’ve done as much as possible with just the spec. That means mapping out the entire API, generating all sorts of mocks, and revising the spec until the whole team is satisfied. Of course, mileage may vary between teams, but this is always a good rule of thumb.

There’s really no reason to start building your API before then; all you end up with is a confused, two-way process where parts of the API are being built to the spec, and parts of the spec are being created retrospectively to match the API.

Of course, you could just discard the spec halfway into the design process – once you’re set on what the API should feel like – but then you’d missing out on a bunch of the benefits of using a spec in the first place, like the automated docs or instant SDKs.

Also, having a current spec continues to prove useful even when you’re already building and implementing your API…

Also check out our lists of Frameworks for building APIs in PHP, Golang, or Node.js.

Always Refer Back to the Spec

Even when your API is fully drafted out, you can keep coming back to the spec for more – and you should!

When building your API, the spec makes an ideal reference point to gauge whether you’re moving in the right direction, and because it can be compressed into just a single file that’s so easy to distribute and read, you can be sure that all your team members are on the same page. This is the “single source of truth” that Jason refers to in his presentation, and it makes everyone’s lives easier.

When implementing your API, the spec has a few great uses which are often overlooked. One of them is validation: you can verify requests against the format in the spec to save you from writing any of the validation logic yourself, and you can make sure the API will meet your chosen development standards by running them over the spec with a tool like OpenAPILint.

Now, all of that validation is only useful if you’re sure the spec matches the implementation in the first place, which is why you’d be silly not to pass some API calls through a proxy like Prism to validate the spec itself!

There’s also routing. You can use your spec to identify what’s internal and external, or what’s proposed and released, during implementation to make sure you don’t accidentally publicize something you shouldn’t.

Benefits of a Specification-First Approach

Having read all that, it’s hard to imagine building an API without a spec. The benefits are endless – from automated docs and SDKs to an improved, more inclusive design experience.

If you enjoyed following Jason’s approach to smart API development, be sure to read his blog post on all the things Typeform is doing to build the best Developer Platform it can.