Skip to main content
Version: 2.15.0-beta

Redocly Config Support

Qraft CLI can use a Redocly configuration file (redocly.yaml) to generate one or multiple API clients with custom settings and authentication rules for both OpenAPI and AsyncAPI documents. By integrating with Redocly's powerful configuration schema resolution, you can streamline client generation across various services defined in your project.

Introductionโ€‹

Qraft CLI integrates with Redocly's configuration framework to simplify API client generation. This integration allows you to:

One config for OpenAPI and AsyncAPIโ€‹

You can keep both modes in the same file:

  • Use x-openapi-qraft for OpenAPI generation options (plugins and OpenAPI-specific flags).
  • Use x-asyncapi-qraft for AsyncAPI generation options (plugins and AsyncAPI-specific flags).
  • Both keys can be set globally and per API entry under apis.<name>.
  • Per-API options override global defaults.

This makes it possible to maintain one redocly.yaml for all services in a project while still using mode-specific plugin options.

Configuration Example: Redocly ๐Ÿค Qraftโ€‹

Here's a basic example of a redocly.yaml configuration file:

# Qraft CLI global OpenAPI config
x-openapi-qraft:
plugin:
tanstack-query-react: true # Generate React Query hooks for each API Client
openapi-typescript: true # Generate TypeScript types for each API Client
clean: true

# Qraft CLI global AsyncAPI config
x-asyncapi-qraft:
plugin:
asyncapi-typescript: true
asyncapi-types-file-name: asyncapi.ts
clean: true

apis:
# Main API configuration
main:
root: ./openapi.json # Path to OpenAPI schema
# Qraft's specific configuration
x-openapi-qraft:
output-dir: src/api # Output directory for a generated API client
clean: true # Clean output directory before generation

# Another OpenAPI entry
payments:
root: ./payments-openapi.json
x-openapi-qraft:
output-dir: src/payments-api
service-name-base: tags

# AsyncAPI entry
hermes:
root: ./asyncapi-hermes.yaml
x-asyncapi-qraft:
output-dir: src/events/hermes
asyncapi-types-file-name: schema.ts

Generating from Redocly Configurationโ€‹

Using the configuration example above, you can generate API clients for all configured OpenAPI and AsyncAPI entries with a single command:

npx qraft redocly

This command will:

  1. Read the redocly.yaml configuration
  2. Generate each API client specified in the configuration

If your configuration file is located elsewhere, you can specify its path:

npx qraft redocly --redocly ./path/to/redocly.yaml

Generating Specific APIsโ€‹

You can also generate clients for specific APIs by listing their names:

npx qraft redocly legacy

This is particularly useful when you want to generate only certain APIs from your configuration.

Authentication Configurationโ€‹

When working with private APIs that require authentication, you can configure authentication headers in your redocly.yaml file. This is particularly useful when your OpenAPI schemas are hosted on private servers or require API keys.

Here's an example of how to configure authentication:

resolve:
http:
headers:
- matches: https://api.example.com/v2/**
name: X-API-KEY
envVariable: API_KEY
- matches: https://example.com/*/test.yaml
name: Authorization
envVariable: AUTH_TOKEN

The CLI will automatically use these credentials when fetching the OpenAPI schemas.

Extended Configuration Exampleโ€‹

Here's a more comprehensive example of a redocly.yaml configuration that demonstrates advanced features:

# Enforce unique operationIds across all operations
rules:
operation-operationId-unique:
severity: 'error'

apis:
main:
root: ../test-fixtures/openapi.json
x-openapi-qraft:
plugin:
tanstack-query-react: true
openapi-typescript: true
output-dir: src/tests/fixtures/api
clean: true
# Force .js/.ts extensions in imports (useful for ESM)
explicit-import-extensions: true
# Custom name for a generated types file
openapi-types-file-name: openapi.ts
# Filter which services to generate
filter-services:
- '/approval_policies/**' # Include all approval policies
- '/entities/**' # Include all entities
- '/files/**' # Include all files
- '!/internal/**' # Exclude internal endpoints
# Set default headers for specific endpoints
operation-predefined-parameters:
'/approval_policies/{approval_policy_id}/**': 'header.x-monite-entity-id'
'/entities/{entity_id}/documents': 'header.x-monite-version'
# Transform operation names using regex
operation-name-modifier:
- '/files/list:[a-zA-Z]+List ==> findAll' # Rename all *List operations to findAll
# Configure custom ParametersWrapper types for specific operations
operation-parameters-type-wrapper:
'get /files/**':
type: 'ReadParametersWrapper'
import: '../../type-overrides/parameters-wrapper.js'
'delete /approval_policies/{approval_policy_id}':
type: 'WriteParametersWrapper'
import: '../../type-overrides/parameters-wrapper.js'
# Override the type imports in the generated code with customs
override-import-type:
services:
'@openapi-qraft/tanstack-query-react-types':
OperationError: '../../type-overrides/operation-error.js'
'@tanstack/react-query':
UseQueryResult: '../../type-overrides/use-query-result.js'
create-api-client:
'@openapi-qraft/react':
CreateAPIQueryClientOptions: '../type-overrides/create-query-client-options.js'
create-predefined-parameters-request-fn:
'@openapi-qraft/react':
QraftPredefinedParameterValue: '../type-overrides/predefined-parameter-value.js'

You can keep AsyncAPI entries in the same config with their own mode-specific options:

apis:
wallet:
root: ./openapi-wallet.json
x-openapi-qraft:
output-dir: src/api/wallet
queryable-write-operations: true
create-api-client-fn:
createAPIClient:
filename: create-api-client
services: all
callbacks:
- useQuery
- useMutation

hermes:
root: ./asyncapi-hermes.yaml
x-asyncapi-qraft:
output-dir: src/api/hermes
asyncapi-types-file-name: asyncapi.ts
alphabetize: true

Generating multiple API client functionsโ€‹

Qraft allows you to generate multiple create API client functions with different parameters using the --create-api-client-fn option. This is particularly useful when you need to create specialized clients for different environments or use cases. For more information on using options, please explore the CLI documentation.

Here's an example of how to configure multiple create API client functions:

apis:
files:
root: ./openapi.json
x-openapi-qraft:
plugin:
tanstack-query-react: true
openapi-typescript: true
output-dir: src/api
# Generate multiple API client functions with different parameters
create-api-client-fn:
# Node.js API client with all services and callbacks
createInternalNodeAPIClient:
filename: create-internal-api-client # Custom filename for the generated function
services: all # Include all services
callbacks: all # Include all callbacks

# React API client with specific callbacks only
createReactAPIClient:
context: APIClientContext # Read baseUrl/requestFn/queryClient from React Context
services: none # Don't include any services directly
callbacks: # Include only specific callbacks
- setQueryData
- getQueryData
- getQueryKey
- getInfiniteQueryKey

Using Context for React Compiler Compatibilityโ€‹

The context option generates a React Context that provides queryClient, requestFn, and baseUrl to the API client. This allows you to create the client outside of React components, making hooks static and compatible with React Compiler.

apis:
main:
root: ./openapi.json
x-openapi-qraft:
plugin:
tanstack-query-react: true
openapi-typescript: true
output-dir: src/api
create-api-client-fn:
# React API client with Context support
createAPIClient:
context: APIClientContext # Generate APIClientContext React Context
callbacks:
- useQuery
- useMutation
- setQueryData
- getQueryData
- getQueryKey
- getInfiniteQueryKey

With this configuration, you can create the API client outside of components:

import { createAPIClient, APIClientContext } from './api';

// Create outside component - hooks are static and React Compiler compatible
const api = createAPIClient();

function MyComponent() {
// Hooks read queryClient, requestFn, baseUrl from APIClientContext
const { data } = api.pets.getPets.useQuery();
return <div>{data?.length} pets</div>;
}

For detailed documentation on using Context-based API clients, see the Context-based API Client documentation.