openskills.info
Open Course

API Design

API design is the practice of defining the contracts that software components use to communicate. It covers choosing interaction styles, naming resources, structuring requests and responses, versioning, error handling, and building interfaces that other developers can adopt without constant guidance.

itSoftware engineering

Don't Panic — API Design

An API is a promise made to people you will never meet, in a language you cannot revise, about behaviour you have not finished implementing. This is fine. Millions of them exist and most of them work.

The central and slightly deflating fact is that API design is barely about URLs. The contract — everything a consumer may rely on — covers which capabilities exist, what the data means, which operations are valid, what happens when things fail, and how any of it may change.

An elegant path cannot rescue an unclear model. Work out the concepts first — which things are distinct entities, which properties may vary, which rules must never break — and the syntax follows.

The commonest way to get this wrong takes ten minutes and feels productive: publishing the database tables directly. Storage exists to make saving data efficient; an API exists to stay useful when the way it is saved changes. Do both jobs with one shape and every future migration becomes a problem for everyone who ever called you.

Then comes the interaction style, a real choice rather than a fashion. HTTP resource APIs suit broad interoperability and predictable behaviour from the caches and proxies in between; GraphQL suits consumers selecting connected data from one typed graph; gRPC suits service methods and streaming; message-driven suits a sender that should not wait for the receiver to care. One system may reasonably speak several, at boundaries chosen deliberately.

Go the HTTP route and the methods already mean things. Some are safe, changing nothing; others are idempotent, so doing them twice leaves the same result as doing them once. Inventing private meanings is how a retry turns into a second order.

A related indignity: HTTP cannot send a later status code for a response it has already finished, so anything long-running needs a separate status resource to come back to. And a request that times out tells the client nothing about whether it worked, which is why what a duplicate does should be decided before a consumer discovers it empirically.

Errors are results, not accidents. Invalid input, missing authentication, denied permission, conflict and exhausted rate limits are five different situations, and collapsing them into one apologetic server error deletes the only information the caller could have acted on. RFC 9457 problem details give a standard shape for saying which. Use it, and keep stack traces out of it.

Then the part everyone underestimates. Deleting something is the obvious way to break a consumer and much the least interesting, because it is deliberate. The expensive breaks look like improvements: a validation rule tightened because the old one was embarrassing, a default corrected, one more value added to a fixed list as the domain grew.

Every one passes the tests, ships on a Tuesday, and arrives in somebody's running code as a surprise. Deprecate early and loudly, and work on the assumption that nothing published can be withdrawn — because mostly it cannot.

Intro next for the whole argument, and the Cheatsheet for the method and status tables when you cannot remember which ones are idempotent.

Where this skill leads

Relevant careers

See how this topic contributes to broader role-level skill maps.

Sources