After this lesson, you will be able to: Write OpenAPI/Swagger specs and generate interactive docs with Swagger UI or Scalar.
OpenAPI is the universal contract format for REST APIs. Generate docs, client SDKs, test mocks. Production APIs without docs feel broken.
A YAML/JSON spec format for describing REST APIs. From the spec you can generate: interactive docs (Swagger UI, Scalar, Redoc), client SDKs (openapi-generator), server stubs, mock servers (Prism), test suites. Standard since ~2015. Every major tool supports it.
YAML for human reading; convert to JSON for tooling.
openapi: 3.1.0info:title: LastWrite Users APIversion: 1.0.0paths:/users:get:summary: List usersresponses:'200':description: List of userscontent:application/json:schema:type: arrayitems:$ref: '#/components/schemas/User'post:summary: Create a userrequestBody:required: truecontent:application/json:schema:$ref: '#/components/schemas/CreateUserInput'responses:'201':description: Createdcontent:application/json:schema:$ref: '#/components/schemas/User''422':$ref: '#/components/responses/ValidationError'components:schemas:User:type: objectproperties:id: { type: integer }email: { type: string, format: email }name: { type: string }required: [id, email, name]CreateUserInput:type: objectproperties:email: { type: string, format: email }name: { type: string, minLength: 1, maxLength: 100 }required: [email, name]responses:ValidationError:description: Validation errorcontent:application/json:schema:$ref: '#/components/schemas/Error'
Single source of truth: Zod schemas → OpenAPI.
// npm i @hono/zod-openapi (Hono) OR zod-to-openapi (framework-agnostic)import { z } from 'zod';import { extendZodWithOpenApi, OpenAPIGenerator, OpenAPIRegistry } from '@asteasolutions/zod-to-openapi';extendZodWithOpenApi(z);const UserSchema = z.object({id: z.number().int(),email: z.string().email(),name: z.string(),}).openapi('User');const registry = new OpenAPIRegistry();registry.registerPath({method: 'get',path: '/users/{id}',request: { params: z.object({ id: z.string() }) },responses: { 200: { content: { 'application/json': { schema: UserSchema } } } },});const spec = new OpenAPIGenerator(registry.definitions, '3.1.0').generateDocument({ info: { title: 'My API', version: '1.0' } });
Spec-first: write OpenAPI, generate server stubs + types. Good for API-first teams. Code-first: write your routes + schemas, generate OpenAPI from them. Good for solo + small teams. Both work. Pick code-first if you're already coding; pick spec-first if you have multi-team contracts.
Hand-written docs that drift from the code (always wrong eventually). Generating OpenAPI but never serving it (you have a spec but no docs UI). Versioning the spec wrong (every release should bump the `info.version`). Forgetting auth in the spec (clients can't tell which routes need auth).
Sign in and purchase access to unlock this lesson.