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 | OpenSkills.info
Course pathWalk it in order
Look it upDip in anytime
Go furtherLeaves this page
Don't Panic
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
- https://www.rfc-editor.org/rfc/rfc9110.html
Supports
- HTTP uniform interface, methods, safety, idempotency, status codes, representations, and content negotiation
- Accepted processing, validators, entity tags, conditional requests, and lost-update prevention
- https://www.rfc-editor.org/rfc/rfc5789.html
Supports
- PATCH method semantics and conditions for issuing an idempotent PATCH request
- https://www.rfc-editor.org/rfc/rfc6585.html
Supports
- 428 Precondition Required and 429 Too Many Requests semantics
- Retry-After guidance for rate-limited requests
- https://www.rfc-editor.org/rfc/rfc9457.html
Supports
- Problem-details media types and standard type, title, status, detail, and instance members
- Stable problem-type identifiers, extension members, documentation, and disclosure risks
- https://spec.openapis.org/oas/v3.2.0.html
Supports
- OpenAPI 3.2.0 as a language-independent HTTP API description
- Paths, operations, parameters, schemas, responses, security schemes, and tooling uses
- https://google.aip.dev/121
Supports
- Resource hierarchies, collections, standard and custom methods, consistency, and stateless interactions
- Avoiding direct coupling between an API surface and its database schema
- https://google.aip.dev/132
Supports
- Standard list request and response structure, page size, page token, filtering, and ordering fields
- https://google.aip.dev/151
Supports
- Durable operation handles, progress observation, terminal results, and execution failures
- https://google.aip.dev/155
Supports
- Client-provided request identifiers, duplicate detection, safe retries, and idempotency guarantees
- https://google.aip.dev/158
Supports
- Pagination contracts, request consistency, next-page tokens, and token opacity
- https://google.aip.dev/180
Supports
- APIs as consumer contracts and backward-compatible versus incompatible schema changes
- Risks from required fields, validation changes, field removal, and enum evolution
- https://spec.graphql.org/September2025/
Supports
- GraphQL typed schemas, documents, validation, execution, and introspection
- Query, mutation, and subscription root operation types
- https://grpc.io/docs/what-is-grpc/core-concepts/
Supports
- Service definitions, message types, unary calls, and three streaming call forms
- https://www.asyncapi.com/docs/reference/specification/v3.1.0
Supports
- Machine-readable message-driven API descriptions
- Channels, operations, messages, servers, bindings, and reusable components
- https://www.rfc-editor.org/rfc/rfc9745.html
Supports
- Deprecation response metadata, deprecation links, and unchanged current resource behavior
- https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
Supports
- Fielding’s 2000 dissertation describing the REST architectural style and its constraints
- https://www.w3.org/TR/soap/
Supports
- SOAP 1.1 publication as a W3C Note on 8 May 2000
- https://www.w3.org/standards/history/wsdl20/
Supports
- WSDL 2.0 Part 1 publication history, including its 26 June 2007 Recommendation
- https://spec.openapis.org/oas/v3.1.0.html
Supports
- OpenAPI revision history: Swagger 1.0 in 2011, Swagger 2.0 in 2014, donation to the OpenAPI Initiative in 2015, OpenAPI 3.0 in 2017, and OpenAPI 3.1 in 2021
- https://grpc.io/blog/ga-announcement/
Supports
- gRPC 1.0 release on 23 August 2016 and its stable core protocol and API surface
- https://www.asyncapi.com/blog/release-notes-2.1.0
Supports
- AsyncAPI 2.0.0 release on 11 September 2019
- https://www.postman.com/api-platform/api-design/
Supports
- Postman API design workflows, including API-first design and OpenAPI definitions
- https://swagger.io/blog/api-design/achieve-api-design-excellence-with-swaggerhub/
Supports
- SwaggerHub design standardization, shared API definitions, style rules, and reusable OpenAPI components
- https://apidog.com/api-design/
Supports
- Apidog design-first OpenAPI workflows, reusable components, collaboration, versioning, mock responses, testing, and generated documentation
- https://redocly.com/pricing
Supports
- Redocly’s API governance, catalog, documentation, and OpenAPI-based monitoring products
- https://scalar.com/products/docs
Supports
- Scalar Docs API references, OpenAPI-powered search, versioned developer documentation, and hosted plans
