How to automatically generate API client libraries from OpenAPI specifications¶
Our services are often split into a backend API and one or more clients of that API. Historically we have spent developer effort in manually keeping API clients in sync with backend APIs. The OpenAPI specification describes a YAML and JSON schema for describing APIs in a machine readable form. OpenAPI specifications are convenient to work with; many of our existing backend libraries generate OpenAPI specifications automatically. Teams may also elect to engage in "specification-first" development where one starts with a description of the API in an OpenAPI file and, from that specification, one generates the backend API implementation.
This how-to guide describes how to generate API clients automatically using features in the common pipeline.
Prerequisites¶
In order to configure OpenAPI-based client generation you will need the following:
- A backend API GitLab project configured to use the common pipeline.
- One of:
- a static OpenAPI specification in a file named
openapi.yaml
in the root of your repository, or - the ability to dynamically generate OpenAPI specifications in CI jobs.
- a static OpenAPI specification in a file named
Deliverables¶
By enabling OpenAPI-based client generation you will get:
- API client libraries built for several languages. Currently this is Python and TypeScript but that list may grow over time.
- Distribution packages for the libraries. For example, wheels are built for the Python client libraries.
- Documentation for the API client packages available in a CI job artefact and, optionally, via GitLab pages.
- Interactive documentation for the API itself available in a CI job artefact and, optionally, via GitLab pages.
- For commits on the default branch, API client libraries published in the GitLab package registry.
Basic usage¶
Add a file named openapi.yaml
to the root of your repository with the OpenAPI schema in it. This
will trigger a run of the OpenAPI client generator. No additional CI configuration is needed.
Warning
OpenAPI clients will only ever be re-generated when openapi.yaml
changes. The version number
of the clients is taken from the OpenAPI specification. Note that neither NPM nor PyPI allow
re-uploading packages with the same version and so you should make sure to change the version
number in openapi.yaml
each time it changes.
Generating the schema in CI¶
If you generate your OpenAPI schema dynamically, you need to explicitly enable OpenAPI client
generation by setting the OPENAPI_GENERATOR_ENABLED
variable. Additionally you'll need to override
the openapi:schema
job to generate your schema and write it to the path stored in the
OPENAPI_GENERATOR_SCHEMA_ARTIFACT_PATH
variable.
For example:
# .gitlab-ci.yml
variables:
# We need to explicitly enable the OpenAPI generation since we don't have an openapi.yaml file in
# the root of our repository.
OPENAPI_GENERATOR_ENABLED: "1"
# We do not ship the OpenAPI schema in the repository and so the openapi:schema job needs to be
# overridden to use our schema generation command.
openapi:schema:
script:
- my-schema-generator --output=$OPENAPI_GENERATOR_SCHEMA_ARTIFACT_PATH
Not that the existing openapi:schema
job's before_script
ensures that the directory containing
that path exists and so you do not need a mkdir
or equivalent.
Warning
The version number of the clients is taken from the OpenAPI specification. Note that neither NPM nor PyPI allow re-uploading packages with the same version and so you should make sure that commits on the default branch always result in an OpenAPI specifications with a unique version number.
Publishing documentation to GitLab pages¶
Documentation artefacts are placed in the directory pointed to by the
OPENAPI_GENERATOR_DOCS_ARTIFACT_DIR
variable. To publish these to GitLab pages, add a pages
job
to your CI configuration. You will need to set needs
and stage
appropriately to guarantee that
the job runs after documentation artefacts have been created:
pages:
stage: production
needs: null
pages: true
script:
# Create the directory holding the GitLab pages content.
- mkdir -p public/
# Copy generated documentation into the GitLab pages directory.
- cp -r "$OPENAPI_GENERATOR_DOCS_ARTIFACT_DIR/*" public/
artifacts:
paths:
- public
rules:
# Only publish to pages for commits to the default branch.
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
Documentation will then be available in subdirectories from your GitLab pages root. For example,
generated documentation for the API itself will appear at .../redoc
and TypeScript client
documentation at .../typescript-axios
.
"Gotchas"¶
The version number of your API clients is taken directly from the version number in the OpenAPI specification. Package managers such as NPM and PyPI disallow re-publishing packages with identical version numbers. As such you need to ensure that, for static OpenAPI files, the version number of the specification increases each time it changes. For OpenAPI specifications generated dynamically bu CI jobs, ensure that each commit to the default branch results in a different version number.
Summary¶
In this guide you learned how to generate and publish API client libraries from OpenAPI specifications either stored in your project's repository or generated dynamically by the backend implementation.
Next steps¶
Read the full reference guide for further customisation.