Skip to content

generate-api Executor

The generate-api executor generates API client code from OpenAPI specifications using your choice of generator plugin.

Terminal window
nx run <project>:generate-api
project.json
{
"targets": {
"generate-api": {
"executor": "@nx-plugin-openapi/core:generate-api",
"options": {
"generator": "openapi-tools",
"inputSpec": "apps/my-app/swagger.json",
"outputPath": "libs/api-client/src"
}
}
}
}

These options are available for all generator plugins.

  • Type: string
  • Default: "openapi-tools"
  • Required: No
  • Description: Specifies which generator plugin to use

Available values:

  • "openapi-tools" - Uses OpenAPI Generator CLI (@openapitools/openapi-generator-cli)
  • "hey-api" - Uses hey-api (@hey-api/openapi-ts)

Examples:

{
"generator": "openapi-tools"
}
{
"generator": "hey-api"
}
  • Type: string | Record<string, string>
  • Required: Yes
  • Description: Path to the OpenAPI specification file(s) or URL(s)

The input specification can be:

  • A single string: Path to one OpenAPI specification (backward compatible)
  • An object: Multiple specifications mapped by service name (for microservices)

For projects with a single API:

{
"inputSpec": "apps/my-app/swagger.json"
}
{
"inputSpec": "https://api.example.com/swagger.json"
}

For microservice architectures with multiple APIs:

{
"inputSpec": {
"ms-product": "apps/my-app/ms-product.json",
"ms-user": "apps/my-app/ms-user.json",
"ms-inventory": "apps/my-app/ms-inventory.json"
}
}

When using multiple specifications:

  • Each key becomes a subdirectory name under outputPath
  • Each API is generated in its own subdirectory
  • All configured options are applied to each generation

Generated structure for multiple specs:

libs/api/src/
ms-product/
// generated API for product service
ms-user/
// generated API for user service
ms-inventory/
// generated API for inventory service
  • Type: string
  • Required: Yes
  • Description: Output directory for the generated API client code

The output directory will be cleaned before generation. Relative paths are resolved from the workspace root.

Examples:

{
"outputPath": "libs/api-client/src"
}
{
"outputPath": "apps/my-app/src/app/generated"
}
  • Type: object
  • Default: {}
  • Required: No
  • Description: Plugin-specific options passed to the generator

This object allows you to pass options specific to the selected generator. The available options depend on which generator you’re using.

Example for OpenAPI Generator:

{
"generatorOptions": {
"configFile": "apps/my-app/openapi-config.json",
"skipValidateSpec": true,
"globalProperties": {
"supportsES6": "true"
}
}
}

Example for hey-api:

{
"generatorOptions": {
"client": "fetch",
"plugins": ["@hey-api/schemas"]
}
}
  • Type: Array<{ name: string; options?: object }>
  • Default: []
  • Required: No
  • Description: Post-processors run in order after a successful generation

Each entry is resolved by name:

  1. Post-processors registered in the PostProcessorRegistry (built-ins or registered programmatically)
  2. Otherwise name is imported as a package. It must export a post-processor as default, postProcessor, or via a createPostProcessor() factory.

options is passed as-is to the post-processor. Steps run sequentially; the first failing step fails the executor and skips the remaining steps. Post-processors are skipped if the generator reports success: false.

Example:

{
"postProcess": [
{ "name": "@my-org/openapi-post-process-lint", "options": { "fix": true } },
{ "name": "@my-org/openapi-post-process-banner" }
]
}

See Creating Plugins for how to write a post-processor.

Splits the generated client into three libs so Nx module boundaries can be enforced on generated code: services get type:api, models get type:types.

LibContentMay import
typesmodels / DTOs (model files)nothing
coreruntime: configuration, http client, utilstypes
apiservices / SDK functionstypes, core

The generator plugin classifies its files via classify() (supported by openapi-tools and hey-api). Then split:

  1. moves model, api and core files to <targetRoot>/{types,api,core}/src/, keeping their relative layout,
  2. rewrites relative imports into another lib to that lib’s alias (import, import type, export ... from, dynamic import(), import('x').T; index and .js extensions are resolved),
  3. writes a src/index.ts barrel per lib,
  4. deletes the generator’s root index.ts barrel. Files classified other (README, metadata, …) stay in place.

Options:

OptionTypeDefaultDescription
aliases{ types: string; api: string; core: string }– (required)Import path alias per lib, e.g. @acme/petstore-types
targetRootstringoutputPathDirectory (relative to the workspace root) receiving the types, api and core libs

Example:

{
"generator": "openapi-tools",
"inputSpec": "libs/petstore/petstore.json",
"outputPath": "libs/petstore/generated",
"postProcess": [
{
"name": "split",
"options": {
"aliases": {
"types": "@acme/petstore-types",
"api": "@acme/petstore-api",
"core": "@acme/petstore-core"
}
}
}
]
}

Result (layout contract for tooling):

libs/petstore/generated/
├── types/src/index.ts # barrel, + model files (e.g. model/pet.ts)
├── api/src/index.ts # barrel, + service files (e.g. api/pet.service.ts)
├── core/src/index.ts # barrel, + runtime files (e.g. configuration.ts)
└── README.md, ... # files classified 'other'

split only owns <lib>/src/**: each run replaces it completely. It does not create project.json files or tsconfig path entries. The aliases must resolve to <targetRoot>/<lib>/src/index.ts (e.g. via tsconfig.base.json paths); the libs are meant to be set up by the add-client generator and inferred as Nx projects by a createNodes plugin.

Notes:

  • targetRoot default: the output path itself, so the libs are regenerated together with the client and never collide with sibling directories. Since the generator cleans outputPath before generating, use a targetRoot outside of it (e.g. libs/petstore) if you need to keep files next to src/ in the lib directories.
  • Boundaries: if the classification produces a forbidden import (e.g. a model importing core), or an import cannot be resolved or points to a file classified other, split fails before writing anything and lists the offending imports.
  • Barrels: re-export top-level files, entry files not imported by other files of the lib (e.g. model/models.ts) and files imported from other libs. If two modules export different bindings with the same name, the first one wins and the later module is re-exported by name without the clashing names.
  • Multiple specs (inputSpec object): each service is split separately into <targetRoot>/<service>/{types,api,core}. Every alias must contain the {service} placeholder, e.g. @acme/{service}-types.
  • classify() options: plugins receive the split options plus generatorOptions and, for multiple specs, service. openapi-tools classifies the typescript-* layouts (tuned for typescript-angular: model/ → types, api/ → api, other top-level files → core; honours apiPackage/modelPackage); unknown files are treated as other with a warning.
  • Requires typescript in the workspace (optional peer dependency of @nx-plugin-openapi/core).

The following options apply when using generator: "openapi-tools". They can be specified directly in options or within generatorOptions.

  • Type: string
  • Default: undefined
  • Description: Path to OpenAPI Generator configuration file

Allows you to specify detailed generation options in a separate JSON file.

Example:

{
"configFile": "apps/my-app/openapi-config.json"
}
  • Type: boolean
  • Default: false
  • Description: Skip validation of the OpenAPI specification

Set to true for faster generation when you’re confident your specification is valid.

Example:

{
"skipValidateSpec": true
}
  • Type: string
  • Default: undefined
  • Description: Authentication configuration for accessing remote specifications

Example:

{
"auth": "bearer:your-api-token"
}
  • Type: string
  • Default: undefined
  • Description: Suffix to append to generated API class names

Example:

{
"apiNameSuffix": "Client"
}
  • Type: string
  • Default: undefined
  • Description: Package name for API classes

Example:

{
"apiPackage": "com.example.api"
}
  • Type: string
  • Default: undefined
  • Description: Package name for the generated client library

Example:

{
"packageName": "@my-org/api-client"
}
  • Type: string
  • Default: undefined
  • Description: Prefix for generated model class names

Example:

{
"modelNamePrefix": "Api"
}
  • Type: string
  • Default: undefined
  • Description: Suffix for generated model class names

Example:

{
"modelNameSuffix": "Model"
}
  • Type: string
  • Default: undefined
  • Description: Package name for model classes

Example:

{
"modelPackage": "com.example.models"
}
  • Type: string
  • Default: undefined
  • Description: Artifact ID for the generated code

Example:

{
"artifactId": "my-api-client"
}
  • Type: string
  • Default: undefined
  • Description: Version of the generated artifact

Example:

{
"artifactVersion": "1.0.0"
}
  • Type: string
  • Default: undefined
  • Description: Group ID for the generated code

Example:

{
"groupId": "com.example"
}
  • Type: boolean
  • Default: false
  • Description: Perform a dry run without actually generating files

Useful for testing configuration without creating files.

Example:

{
"dryRun": true
}
  • Type: boolean
  • Default: false
  • Description: Enable post-processing of generated files

Example:

{
"enablePostProcessFile": true
}
  • Type: boolean
  • Default: false
  • Description: Only update files that have actually changed

Example:

{
"minimalUpdate": true
}
  • Type: boolean
  • Default: false
  • Description: Skip overwriting existing files

Example:

{
"skipOverwrite": true
}
  • Type: boolean
  • Default: false
  • Description: Remove operation ID prefixes from generated method names

Example:

{
"removeOperationIdPrefix": true
}
  • Type: boolean
  • Default: false
  • Description: Skip generating operation examples in the code

Example:

{
"skipOperationExample": true
}
  • Type: boolean
  • Default: false
  • Description: Use strict specification validation

Example:

{
"strictSpec": true
}
  • Type: string
  • Default: undefined
  • Description: Directory containing custom templates for code generation

Example:

{
"templateDirectory": "apps/my-app/templates"
}
  • Type: string
  • Default: undefined
  • Description: Path to a custom ignore file

Example:

{
"ignoreFileOverride": "apps/my-app/.openapi-generator-ignore"
}
  • Type: object
  • Default: undefined
  • Description: Global properties for the OpenAPI Generator

An object where keys are property names and values are property values.

Example:

{
"globalProperties": {
"supportsES6": "true",
"npmName": "@my-org/api-client",
"npmVersion": "1.0.0",
"providedInRoot": "true",
"withInterfaces": "true"
}
}
  • Type: string
  • Default: undefined
  • Description: Custom HTTP user agent string

Example:

{
"httpUserAgent": "MyApp/1.0.0"
}
  • Type: string
  • Default: undefined
  • Description: Release notes for the generated code

Example:

{
"releaseNote": "Initial release of the API client"
}
  • Type: string
  • Default: undefined
  • Description: Root directory for input specifications

Example:

{
"inputSpecRootDirectory": "specs/"
}
  • Type: string
  • Default: undefined
  • Description: Package name for invoker classes

Example:

{
"invokerPackage": "com.example.invoker"
}
  • Type: string
  • Default: undefined
  • Description: Git host for the repository

Example:

{
"gitHost": "github.com"
}
  • Type: string
  • Default: undefined
  • Description: Git user ID

Example:

{
"gitUserId": "my-username"
}
  • Type: string
  • Default: undefined
  • Description: Git repository ID

Example:

{
"gitRepoId": "my-api-client"
}
  • Type: boolean
  • Default: false
  • Description: Log output to stderr instead of stdout

Example:

{
"logToStderr": true
}

Here’s a comprehensive example showing many options:

project.json
{
"targets": {
"generate-api": {
"executor": "@nx-plugin-openapi/core:generate-api",
"options": {
"inputSpec": "apps/demo/swagger.json",
"outputPath": "libs/api-client/src",
"configFile": "apps/demo/openapi-config.json",
"packageName": "@my-org/demo-api-client",
"apiNameSuffix": "Service",
"modelNamePrefix": "Api",
"modelNameSuffix": "Model",
"skipValidateSpec": false,
"strictSpec": true,
"globalProperties": {
"supportsES6": "true",
"npmName": "@my-org/demo-api-client",
"npmVersion": "1.0.0",
"providedInRoot": "true",
"withInterfaces": "true"
}
},
"outputs": ["{options.outputPath}"]
}
}
}

For microservice architectures:

project.json
{
"targets": {
"generate-api": {
"executor": "@nx-plugin-openapi/core:generate-api",
"options": {
"inputSpec": {
"auth-service": "apis/auth-service.yaml",
"product-service": "apis/product-service.yaml",
"order-service": "apis/order-service.yaml",
"payment-service": "apis/payment-service.yaml"
},
"outputPath": "libs/api-clients/src",
"packageName": "@my-org/api-clients",
"apiNameSuffix": "ApiService",
"modelNamePrefix": "Api",
"globalProperties": {
"supportsES6": "true",
"providedInRoot": "true",
"withInterfaces": "true"
}
},
"outputs": ["{options.outputPath}"]
}
}
}

This will generate:

libs/api-clients/src/
auth-service/
// Auth API client
product-service/
// Product API client
order-service/
// Order API client
payment-service/
// Payment API client

Use configurations for different environments:

project.json
{
"targets": {
"generate-api": {
"executor": "@nx-plugin-openapi/core:generate-api",
"options": {
"inputSpec": "apps/demo/swagger.json",
"outputPath": "libs/api-client/src"
},
"configurations": {
"development": {
"inputSpec": "http://localhost:3000/api/swagger.json",
"skipValidateSpec": true
},
"production": {
"inputSpec": "https://api.prod.example.com/swagger.json",
"strictSpec": true
}
}
}
}
}

Run with configuration:

Terminal window
nx run demo:generate-api:development

The following options apply when using generator: "hey-api". Pass them via generatorOptions.

OptionTypeDescription
clientstringHTTP client to use ("fetch", "axios", etc.)
pluginsarrayArray of plugins to enable
schemasobjectSchema generation configuration
servicesobjectService generation configuration
typesobjectType generation configuration

For a complete list of options, see the hey-api documentation.

project.json
{
"targets": {
"generate-api": {
"executor": "@nx-plugin-openapi/core:generate-api",
"options": {
"generator": "hey-api",
"inputSpec": "apps/demo/openapi.yaml",
"outputPath": "libs/api-client/src",
"generatorOptions": {
"client": "fetch",
"plugins": [
"@hey-api/schemas",
"@hey-api/services",
"@hey-api/types"
]
}
},
"outputs": ["{options.outputPath}"]
}
}
}
project.json
{
"targets": {
"generate-api": {
"executor": "@nx-plugin-openapi/core:generate-api",
"options": {
"generator": "hey-api",
"inputSpec": {
"users": "apis/users-api.yaml",
"products": "apis/products-api.yaml"
},
"outputPath": "libs/api-clients/src",
"generatorOptions": {
"client": "axios"
}
},
"outputs": ["{options.outputPath}"]
}
}
}