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()

How Optic can help you

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 and Documentation. The 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.

The Documentation ruleset enforces that operations must have an operationId, a summary and/or a description.

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.

Want to ship a better API?

Optic makes it easy to publish accurate API docs, avoid breaking changes, and improve the design of your APIs.

Try it for free