Lesson 24 / 25

Case Study: Designing an Orders API Contract

Apply the course to design, review and publish a realistic API contract.

From requirements to a published contract

A team must expose orders to a mobile app and to delivery partners. Design-first: they write orders-api/openapi.yaml in OpenAPI 3.1, splitting schemas and paths into files. Resources: GET /orders (cursor pagination, filters by status and date), POST /orders (requires an Idempotency-Key header, returns 201 with Location), GET /orders/{orderId}, POST /orders/{orderId}/cancellation, and POST /orders/{orderId}/attachments (multipart). Schemas: Order, OrderItem, Money as decimal strings, and a oneOf PaymentMethod with a discriminator. Errors: shared Problem Details responses for 400, 401, 403, 404, 409, 422 and 429. Security: OAuth 2.0 authorization code with PKCE for the app (orders:read, orders:write scopes), client credentials for partners, and a public health check. Events: an orderShipped webhook with an HMAC signature header. The pull request runs Spectral and oasdiff; the mobile team builds against a Prism mock while the backend implements Spring interfaces generated with OpenAPI Generator; Schemathesis runs against each build; and merges publish Redoc docs and a TypeScript SDK.

The contract outline

Paths, components and workflow at a glance.

orders-api/
  openapi.yaml            openapi 3.1.0, info, servers, tags, security, paths -> $refs, webhooks
  paths/
    orders.yaml           GET list (limit, cursor, status[], createdAfter), POST create (Idempotency-Key)
    order.yaml            GET by id
    cancellation.yaml     POST cancel
    attachments.yaml      POST multipart upload (application/pdf)
  schemas/
    order.yaml, order-item.yaml, payment-method.yaml (oneOf + discriminator), order-page.yaml
  webhooks/
    order-shipped.yaml    X-Signature header, retries documented
  components from common/v1: Problem, Money, Limit, Cursor, standard error responses

pipeline: spectral lint -> redocly bundle -> oasdiff breaking -> publish Redoc + TS SDK + Prism mock
implementation: spring generator (interfaceOnly) + Schemathesis contract tests in CI

Review with real consumers

Before implementation, walk through the contract with the mobile and partner teams using the mock server. Questions like "how do I know a cancellation succeeded?" are cheap to answer in YAML and expensive after release.

Quick check: In the case study, how can the mobile team start work before the backend is implemented?

  • They build against a Prism mock server generated from the OpenAPI document
  • They wait for the release
  • They read the database schema
  • They use the production API
Answer

They build against a Prism mock server generated from the OpenAPI document — Mock servers driven by the contract allow parallel development.