Home / Blog / Doc-first API development with OpenAPI: the discipline that pays off

Doc-first API development with OpenAPI: the discipline that pays off

Writing docs after the fact is an anti-pattern. Four practical wins from writing the OpenAPI spec first.

The typical API development pattern: the backend gets coded, the code stabilizes, then someone writes docs, the docs drift out of sync, nobody maintains them.

Doc-first is the opposite: write the OpenAPI spec first, treat the spec as the source of truth, generate code and docs from the spec (or keep them in sync manually when generation isn’t possible). Projects where I’ve used this discipline turn out dramatically better.

This post covers the practical wins and how I set it up.

OpenAPI, quick refresher

OpenAPI (formerly Swagger) is a standard for describing REST APIs. YAML or JSON. Endpoints, request/response schemas, authentication, errors: it all goes in.

Basic example:

openapi: 3.0.3
info:
  title: My API
  version: 1.0.0
paths:
  /users/{id}:
    get:
      summary: Get user by ID
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
components:
  schemas:
    User:
      type: object
      properties:
        id: { type: string }
        name: { type: string }
        email: { type: string }

Readable, version controllable, machine-parseable for validation.

Benefit 1: design review before implementation

Traditional flow: backend implements an endpoint, frontend sees it, “this shape is wrong”, backend changes it. Two or three iterations.

Doc-first: the OpenAPI spec goes up in a PR. Frontend developer, backend developer, product manager all review. Once the spec is approved, implementation starts.

Upshot:
– Wrong field names get caught early
– Missing edge cases (pagination, filtering) show up in the spec
– Frontend development starts in parallel with backend (using a mock server)

On my projects spec review takes one to two hours. Skipping it costs a week.

Benefit 2: code generation

You can generate code automatically from the OpenAPI spec:

Backend models:
– openapi-generator-cli produces Go/Python/Node.js structs.
– When the spec changes, structs update automatically.

API client libraries:
– TypeScript client for the frontend (type-safe fetch calls).
– Swift package for iOS.
– Kotlin library for Android.
– Each platform gets its own native client.

Example:

openapi-generator-cli generate 
  -i openapi.yaml 
  -g typescript-axios 
  -o ./frontend/src/api-client

The frontend developer gets typed functions:

const user = await api.users.getUser({ id: '123' });
// user: User type

Auto-generated, type-safe client instead of hand-rolled fetch calls.

Benefit 3: mock server (parallel development)

Generate a mock server from the OpenAPI spec. The frontend stops waiting for the backend to ship.

Tools:
Prism: prism mock openapi.yaml, one command, mock server up.
Stoplight Prism: CLI plus cloud versions.
MockAPI: SaaS, mock through a web UI.

Frontend developer:

fetch('http://localhost:4010/users/123')
// Mock response: example data from spec

Backend developer builds the real endpoint in parallel. Because both work off the same spec, there’s minimal friction at integration time.

Benefit 4: documentation that’s always current

Biggest pain point with traditional flows: the docs don’t match the code. Six months later you notice nobody updated the docs.

In a doc-first approach:

  • The spec lives in the code repo
  • Every PR updates the spec too (or the reviewer asks for it)
  • Generated client libraries regenerate on every build, stale code doesn’t compile
  • Swagger UI / Redoc renders the spec in real time

Docs aren’t a “snapshot from one day”; they’re the live API surface.

Tool ecosystem

The OpenAPI tool ecosystem is strong:

Writing specs:
– Stoplight Studio: visual editor
– Swagger Editor: web-based
– VS Code OpenAPI extension

Rendering:
– Swagger UI: classic interactive docs
– Redoc: modern, cleaner
– Stoplight Elements: embeddable component

Validation:
– Spectral: lint rules for OpenAPI specs
– openapi-validator: schema conformance

Testing:
– Dredd: compares spec to actual API (contract testing)
– Postman: spec import, test collections

Mock:
– Prism: CLI mock server
– MockServer: advanced mock with recording

Practical workflow

My actual workflow:

1. Design phase (1 to 2 days):
– Spec the feature with the PM: endpoints, user journey
– Write the first OpenAPI draft
– Open it as a PR titled “[SPEC] User Management API v1”

2. Review phase (1 to 2 days):
– Frontend, backend, QA review
– Schema fields debated
– Edge cases added (error responses, pagination)
– PR merged

3. Parallel implementation (1 to 2 weeks):
– Backend implements the real endpoint
– Frontend builds against the auto-generated TypeScript client
– QA generates a Postman collection from the spec

4. Integration (1 to 2 days):
– Backend endpoint tested from the frontend
– Contract testing (Dredd) checks spec vs implementation
– If anything diverges, it’s a spec-vs-code debate (usually the spec wins, because it was reviewed)

5. Release:
– Swagger UI auto-generated
– Public API documentation site
– Client libraries published as versioned packages

This workflow adds about a week to the early design phase of a 3 to 5 week feature. But it cuts 2 to 3 weeks off integration bugs. Net gain: about 30% throughput.

Common anti-patterns

1. Writing the spec after the code. That’s not doc-first. Generic documentation buys you much less here.

2. Changing code without updating the spec. One or two months later the spec is stale, nobody trusts it. Takes team discipline.

3. Spec too simple. Only the happy path. Error responses and edge cases missing. Every response code should be in the spec.

4. Tooling overload. Ten different tools, none of them fully set up. Minimum: Swagger UI (docs) + Prism (mock) + openapi-generator (client libs).

Migration: moving an existing API to doc-first

Retrofitting an existing API into OpenAPI is a big job. Strategy:

Phase 1: spec the current version. Document every endpoint, update the implementation to match the spec where tests are missing.

Phase 2: new features go doc-first.

Phase 3: gradually move legacy endpoints into the spec.

A 6 to 12 month effort, but a good investment. Makes large APIs much easier to maintain.

OpenAPI 3.0 vs 3.1

Version choice:

  • OpenAPI 3.0: mature, broad tool support. Most common.
  • OpenAPI 3.1: compatible with JSON Schema Draft 2020, better schema features.

Write new projects in OpenAPI 3.1. Existing projects can stay on 3.0.

Security in OpenAPI

Auth mechanisms live in the spec:

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

paths:
  /users:
    get:
      security:
        - bearerAuth: []
      # ...

Every endpoint’s security requirement is in the spec. Swagger UI gets an “Authorize” button for interactive testing.

Monorepo vs split

Where should the spec live?

Single repo (monorepo): openapi.yaml in the backend repo. Client libraries in a separate directory inside the monorepo.

Spec repo: a dedicated repo just for the API spec. Backend and clients consume it.

Monorepo is easier for small teams. Multi-team enterprises often need a separate spec repo to enforce discipline.

Bottom line

Doc-first API development is discipline-intensive but high leverage. Design review happens early, the frontend works in parallel, client libraries are auto-generated, docs stay current.

The OpenAPI ecosystem is mature. Initial setup is a one to two week job. After that, every new API feature takes two or three hours of spec writing, and saves two or three weeks of integration bugs. The ROI is positive.

Start small: spec one endpoint, render Swagger UI, do a review. If the feedback is positive, extend it across the whole API.

Have a project on this topic?

Leave a brief summary — I’ll get back to you within 24 hours.

Get in touch