Code Generation
Last updated
Was this helpful?
Last updated
Was this helpful?
We use code generation to automatically generate API schemas and type-safe clients for all API integrations. All generated files are ignored by git to reduce noise, make reviews easier on PRs, and only request code reviews from relevant teams.
You will need java
installed on your machine to be able to run the yarn codegen
command, more precisely the openapi-generator
sub-command. Find more about the installation .
We are only tracking file that are coming from an external source, e.g. contentfulTypes.d.ts
which depends on Contentful to be generated. The same goes for openapi.yaml
files from external services.
Running yarn codegen
will generate all the schemas and clients for the project. It can take up to 10 minutes to run. The output of each step is cached by NX and subsequent runs will usually be much faster.
In our GitHub workflows, we are caching theses generated files to avoid to re-generate them at each push. However, the generated files have to be updated when some specific files are changed (e.g. *.resolvers.ts
, *.dto.ts
, etc). There is a hashFiles variable in our GitHub workflows which contain a list of file patterns which may affect code generation† and are used to invalidate the cache. You should follow this naming convention for files which need to invalidate the code generation cache.
We have 3 different targets that can be configured inside project.json
to generate schemas and types.
codegen/backend-client
codegen/backend-schema
codegen/frontend-client
These are designed with smart defaults and run in the correct order thanks to the NX dependency graph.
If you are changing some API service, you may need to re-generate the API schema using:
With an updated API schema, you may need to re-generate client code with:
If you have changed a public API schema, you may need to re-generate front-end client code with:
The following guides cover how to set up code generation in your project.
First, you need to create an openApi.ts
file to define the document builder. Add this file to the src
directory of your project alongside the index.ts
.
Next, we need to create an buildOpenApi.ts
that will consume the previous file and generate the openapi.yaml
file.
Finally, we set up a codegen/backend-schema
script in project.json
for the project.
If your service is running a service like redis, you will need to ignore it for running the build-open-api script like follow in the project.json
and in the module where the redis manager is defined
This is similar to generating OpenAPI schemas. Configure your app module to generate a schema file at startup like this:
For the codegen/backend-schema
build target, you can use the build-graphql-schema.ts utility to load your AppModule and generate the GraphQL schema:
You'll also need to add an implicit dependency from the client project to the API project (also in project.json
. This is to make sure NX first runs the schema target of the API project before running the client target of the client project.
Creating client libraries for external APIs is similar. You should ask the API provider for an OpenAPI schema and add it to our monorepo in your client project. Name it something like clientConfig.json
(don't name it openapi.yaml
which is ignored by git). Then add a codegen/backend-client
build target project.json
:
In many cases you can download the OpenAPI schema directly from running servers. In that case it is handy to define a update-openapi-document
build target in the client project. Something like this:
Create a codegen.yml
file in your project:
Finally, you can configure a codegen/frontend-client
inside your project.json
Instead of generating one big TypeScript file in each project, you might want to use the near-operation-file
preset. It creates small TypeScript files with hooks and operation types for operations defined in graphql files. These can be next to where they're used.
Make sure to configure the codegen/frontend-client
outputs to match:
You can use and the OpenAPI schema generated above to generate a type-safe client library to integrate with it. Just create a client project and add the following target to the project.json
.
In case the API is on X-Road / Straumurinn and you're running , you can fetch OpenAPI schemas for REST APIs with a build target like this:
You can use to generate all kinds of TypeScript types and even React hooks to integrate with GraphQL APIs.
You can also use GraphQL Code Generator to integrate a GraphQL API inside a backend client project. You can explore which plugins and presets . In the least you can use it to validate your operations against the schema, and generate TypeScript types which you then use manually, eg with .