Make sure your OpenAPI has accurate examples and descriptions
Nicholas Lim 2023-11-8
Good API documentation can make integrating an API a breeze instead of a chore. A well-maintained API that is documented with request/response body examples and endpoint descriptions makes it easy for users to understand and know what to expect.
API documentation can also make it easier for code generators and other tools that use OpenAPI to generate meaningful output. For example, client SDK generators use the
operationId field in the operation to assign a meaningful name to an operation and including a description can be used to generate tooltips in client SDKs.
# OpenAPI paths: /api/users: get: operationId: getAllUsers ...
// Typescript code backendClient.getAllUsers()
We’ve all tried keeping documentation up to date, there’s usually a big push that makes documentation a priority, but then it slowly gets neglected. Optic helps you ensure your API is high quality and lets you roll out these changes incrementally.
Optic comes with two built in rulesets,
Examples ruleset enforces that all endpoints must have examples, and that those examples must match the schema, something that usually requires you to manually compare the example to the schema.
schema: type: object properties: id: type: string name: type: string example: id: 123 name: Joe
The above schema does not match the example.
Documentation ruleset enforces that operations must have an
summary and/or a
Using these rulesets, we can also specify that they are only applied to new endpoints or for certain types of endpoints. This is great if you want to roll out changes incrementally and avoid adding documentation and examples to your entire API at once.
To get started, start by downloading Optic
npm i -g @useoptic/optic
Next, create an
optic.yml in the root of your repository with the following ruleset configuration (see https://www.useoptic.com/docs/style-guides (opens in a new tab) for other rulesets you can configure).
ruleset: - examples: # This will apply the rule to only new names (existing ones will be exempted) # Change to always if you want to fail on legacy names required_on: added # Turn on/off the parts of the spec that need examples require_request_examples: true require_response_examples: true require_parameter_examples: true # (optional) allow certain operations do not need examples exclude_operations_with_extension: x-legacy-api # Require documentation in your OpenAPI spec - documentation: # This will apply the rule to only new names (existing ones will be exempted) # Change to always if you want to fail on legacy names required_on: added require_property_descriptions: true require_operation_summary: true require_operation_description: true require_operation_id: true # (optional) allow certain operations do not need examples exclude_operations_with_extension: x-legacy-api
Next, you can run these checks against an OpenAPI spec. Since we are only requiring documentation and example on new endpoints, we need to provide a before and after spec. In Optic, we use
optic diff --check to compare and run change based rules.
optic diff openapi.yml --check --web --base HEAD~1
You can change
--base to any
git reference (like
main or a specific commit hash).
Using diff and rulesets are a great way to incrementally add descriptions and examples to your API. The last thing to do here is to set up Optic in CI so that these rules run on every change.