OpenAPI
A standard specification for defining HTTP APIs, enabling code generation for servers, clients, and documentation.
OpenAPI is a standard for describing HTTP APIs in a machine-readable format (YAML or JSON). You define your endpoints, request/response schemas, and authentication in a single spec file. Then you generate server stubs, client libraries, and documentation from it.
The approach is sometimes called "API-first" or "contract-first" design. Instead of writing Go structs and hoping the frontend matches, you write the spec once and generate code for both sides. If someone changes the API, they update the spec and regenerate. Breaking changes show up as compile errors, not during runtime.
In Go, we recommend oapi-codegen for server and client generation. It produces typed request/response structs, routing setup, and parameter parsing. You implement an interface (the StrictServerInterface), and the generated code handles the HTTP plumbing. It works with popular routers like Echo and chi.
For frontend clients (JavaScript, TypeScript), openapi-generator-cli does the equivalent job.
Another approach is generating the OpenAPI spec from Go code. Tools exist for this, but the OpenAPI specification is rich, and Go annotations can't express all of it. It's much easier to go the other way: write the spec, generate the code.
A very common trap is reusing OpenAPI-generated structs as domain or database models. The generated types represent the API contract. They belong in the adapters layer, not in your business logic. Mixing them couples your API shape to your storage, which is exactly the kind of tight coupling that Clean Architecture exists to prevent.
The spec also gives you documentation for free. Tools like Swagger UI can render it as interactive API docs without any extra work.
OpenAPI plays a similar role to Protocol Buffers for gRPC: both define a contract and generate code from it. The difference is that OpenAPI targets HTTP/JSON APIs, while protobuf targets gRPC with binary serialization. gRPC's code generation is stricter, but OpenAPI covers the more common case of REST-style APIs.
References
- The Go libraries that never failed us: 22 libraries you need to know — Dedicated section on OpenAPI tooling in Go. Recommends oapi-codegen for generating Go servers and clients from OpenAPI specs, and openapi-generator-cli for JavaScript/TypeScript clients. Advises against generating specs from code.
- Building a serverless application with Go, Google Cloud Run and Firebase — Uses OpenAPI to generate both a Go HTTP server and a JavaScript client from a shared spec. Shows how generated models and routing reduce boilerplate and keep the API contract consistent across the stack.
- Robust gRPC communication on Google Cloud Run (but not only!) — Compares gRPC with OpenAPI for service contracts. Notes that gRPC's code generation is stricter than OpenAPI's, which copies structures rather than enforcing types at compile time.
- When to avoid DRY in Go — Illustrates a DRY pitfall where sharing an OpenAPI-generated struct for both the API response and the database model creates tight coupling between layers.
- Common Anti-Patterns in Go Web Applications — Recommends generating HTTP models and routes from OpenAPI definitions using oapi-codegen to avoid hand-written boilerplate and keep API contracts in sync.
- How to use basic CQRS in Go — Explains why structures generated from OpenAPI shouldn't be reused as domain models, referencing the DRY and Clean Architecture articles.
- Microservices test architecture. Can you sleep well without end-to-end tests? — Uses HTTP clients generated by oapi-codegen in tests, making it easy to call endpoints without manually constructing HTTP requests and parsing JSON.
- You should not build your own authentication — Shows how to configure authentication on OpenAPI-generated clients by setting the bearer token from Firebase Auth on the generated JavaScript API client.
- 4 practical principles of high-quality database integration tests in Go — Mentions OpenAPI alongside protobuf as tools for robust service contracts that increase confidence in integration tests.
- The Repository pattern in Go: a painless way to simplify your service logic — Shows an example where database models are based on Swagger-generated models, illustrating how OpenAPI types can leak into the data layer when layers aren't properly separated.
- OpenAPI 3.0 Specification
- oapi-codegen: Generate Go code from OpenAPI 3 specs