skip to content

Codegen & Tooling

Generated stubs and SDKs, Swagger UI and Redoc docs, Spectral linting, and the contract-first versus code-first choice beneath them. Interviewers ask because that workflow shapes every consumer.

part ofAPI stylesoverview, primer and where to startread it →
on this pageshow

questions

6

In an OpenAPI workflow, what is the difference between contract-first and code-first, and what does each cost?

level: middleimportance: must knowfreq 68%

answer

  1. Which artefact is authoritative
  2. Derivation runs one way or the other
  3. Mocks before implementation exists
  4. Generated specs are always fresh, never reviewed
  5. Commit the generated file and diff it

basics

~20 s

Contract-first treats the hand-written OpenAPI document as the source of truth and derives code from it; code-first treats the implementation as the truth and generates the document from annotations. The first buys design review and parallel work, the second buys speed and automatic freshness.

solid answer

~50 s

In **contract-first**, the document is authored and reviewed before implementation, then drives everything downstream — server interfaces, client SDKs, mock servers. Consumers can start against a mock the day the spec merges, the API gets reviewed as a design artefact rather than discovered after release, and every language sees the same contract. The costs are real: someone must be fluent in OpenAPI, generators constrain what you can express, and the implementation can still drift from the document unless something checks. In **code-first**, annotations on the implementation produce the document. It is cheaper to start, and the spec always reflects the code that generated it — but the API is designed implicitly, the published contract can change silently because someone renamed a field, and the document inherits the framework's serialisation quirks. The pragmatic middle is code-first with the generated spec committed and a CI check that fails on an unreviewed diff.

go deeper

for a junior

Be able to state which artefact is authoritative in each approach and that everything else is derived from it.

for a middle

Explain the tradeoffs concretely: mock servers and design review versus speed and automatic freshness, and why a generated spec is fresh but unreviewed.

for a senior

Show the enforcement thinking — generated interfaces that break the build, a committed spec with a CI diff gate, and where drift actually creeps in under each approach.

for a principal

Own the fleet-level decision: which services must be contract-first, how SDKs are produced and supported, and the migration cost of changing direction across many teams.

## Two directions of derivation The difference is simply which artefact is authoritative. **Contract-first**: a human writes the OpenAPI document. Everything else — server interfaces, client SDKs, mocks, documentation — is derived from it. The document is reviewed like any design. **Code-first**: a human writes the implementation, annotated with metadata; a library walks the running application or its types and emits the document. The document is a build output. Everything else follows from that choice of direction. ## What contract-first buys **Design review before implementation.** The API surface arrives as a reviewable diff before anyone builds it. Naming, resource shape and error modelling get argued when changing them is free, not after a client has integrated. **Parallel work.** A merged spec can drive a mock server immediately, so consumers build against a realistic API while the implementation is still in progress. On a project with a separate frontend or partner team, this alone often justifies the approach. **Cross-language consistency.** Every SDK is generated from one document, so field names, nullability and error shapes are identical everywhere. In code-first, each service's spec reflects its own framework's conventions and the fleet drifts apart. **Compile-time enforcement.** When the server implements a generated interface, a contract change breaks the build at the exact points that no longer satisfy it — the strongest guarantee available that code and contract agree. ## What contract-first costs **Skill and time.** Somebody must know the specification well. Badly hand-written specs — untagged operations, missing operation ids, anonymous inline schemas — produce worse SDKs than a decent code-first setup. **Generator constraints.** You end up designing within what generators handle well across your target languages. Advanced schema composition is supported unevenly, and discovering that after the design review is expensive. **Friction on small changes.** Adding one field means editing the spec, regenerating, and implementing — heavier than typing a field into a class. **Drift is still possible.** Implementing a generated interface prevents it structurally; hand-implementing against a document does not. Without a check, contract-first can be exactly as wrong as code-first, only with more ceremony. ## What code-first buys and costs It is fast to adopt: annotate, and the document appears. The output is always consistent with the code that produced it at that moment, which is genuinely valuable — there is no separate artefact to forget. The costs are subtler. The API is designed by accident: whatever the class hierarchy happens to serialise to becomes the contract, and internal refactors surface as public changes. Nothing forces a review of the API surface itself, so a renamed field ships as a breaking change nobody discussed. Descriptions and examples are annotation clutter, so they tend to be sparse and the rendered documentation is thin. And the document inherits framework quirks — how the serialiser represents dates, empty collections and polymorphic types leaks into the published contract. ## The hybrid most teams land on Generate the spec from code, **commit the generated document**, and have CI regenerate it and fail if the committed file differs. That gives three properties at once: the spec cannot drift (the check enforces it), every contract change becomes a visible diff in code review (so nobody renames a public field by accident), and you keep code-first's low ceremony. Layer a linter on top for house style and a breaking-change diff against the last published version, and you have most of contract-first's discipline without hand-authoring. ## Choosing Contract-first pays off when multiple teams or external partners consume the API, when several languages need SDKs, or when the API is the product. Code-first fits an internal service with one consumer moving fast. The choice is not permanent — but migrating a fleet is expensive, so it is worth making deliberately rather than defaulting to whatever the framework does out of the box.

  • Does contract-first guarantee the implementation matches the document?
    Only if something enforces it. Generating server interfaces and implementing them does — a contract change breaks the build at the mismatch. Hand-implementing against a document does not; then contract-first drifts exactly like code-first, just with more ceremony. The guarantee comes from the enforcement mechanism, not the authoring order.
  • What is the cheapest way to get code-first's convenience without losing review of the API surface?
    Commit the generated document and add a CI step that regenerates it and fails when the committed file differs. Every contract change then appears as a reviewable diff in the pull request, so a renamed public field cannot ship unnoticed, and the committed spec can never go stale.
  • Why do code-first specs tend to produce thinner documentation?
    Because prose lives in annotations, which are tedious to write and easy to skip, so `description`, `summary` and `example` fields end up sparse. Renderers show only what the document contains, so the published page degrades to a field list. The document also inherits the serialiser's representation choices rather than deliberate contract design.

saying these in an interview costs you the question

  • Says contract-first prevents drift with no enforcement
  • Treats a generated spec as reviewed because it is accurate
  • Claims code-first cannot produce usable SDKs
  • Thinks the choice is purely about developer preference
  • Ignores that internal refactors become public contract changes

context

open as a page

In openapi-generator, what do you get from a server stub versus a client SDK for the same spec?

level: middleimportance: must knowfreq 62%

basics

~20 s

Both derive models from the spec's schemas, but a server generator emits routing or controller interfaces you implement, while a client generator emits a ready-to-call HTTP client. The generator is chosen with -g, and operationId and tags determine method and class names.

open as a page

What is the difference between Swagger UI and Redoc for rendering an OpenAPI document?

level: juniorimportance: should knowfreq 40%

basics

~20 s

Both render the same OpenAPI document as HTML. Swagger UI is an interactive explorer whose Try it out sends real requests from the browser; Redoc is a read-only three-panel reference page. The choice is interactivity versus a clean published reference.

open as a page

How do you wire openapi-generator into a build so generated code stays maintainable?

level: seniorimportance: should knowfreq 42%

basics

~20 s

Generate into a build output directory, never hand-edit the result, pin the generator version so output does not shift under you, and wrap generated clients behind your own interface. Then decide deliberately whether to commit the output or regenerate it every build.

open as a page

How would you enforce OpenAPI style rules across many specs in CI using Spectral?

level: seniorimportance: should knowfreq 34%

basics

~20 s

Publish one shared Spectral ruleset that each repository extends, define rules as a JSONPath given plus a then function and severity, run spectral lint in CI, and gate the build with --fail-severity. Introduce new rules at warn before promoting them to error.

open as a page

How would you stop published OpenAPI documents from drifting away from the running services?

level: principalimportance: should knowfreq 26%

basics

~20 s

Make the document impossible to bypass: one generation path per service, a CI check that fails when the regenerated spec differs from the committed one, publication from the deploy pipeline rather than by hand, and runtime checks that responses still match the schemas.

open as a page