Generation
There are three ways to generate declared exports:
| Method | Best For |
|---|---|
| Endpoints | Development |
| Rake Tasks | Production |
| Programmatic | Custom |
Endpoints
Each declared export is available as an endpoint at the API's base path:
| Format | Endpoint |
|---|---|
| OpenAPI | GET /api/v1/.openapi |
| TypeScript | GET /api/v1/.typescript |
| Zod | GET /api/v1/.zod |
Endpoints are only available in development by default and generate on each request, so changes to the API definition are reflected immediately.
Query Parameters
Options are passed as query parameters:
curl http://localhost:3000/api/v1/.openapi?format=yaml
curl http://localhost:3000/api/v1/.typescript?key_format=camelUniversal options (available for all exports):
| Parameter | Values | Default |
|---|---|---|
key_format | keep, camel, pascal, kebab, underscore | API's key_format |
locale | Any locale symbol | — |
Serialization (hash exports only):
| Parameter | Values | Default |
|---|---|---|
format | json, yaml | json |
Each export may define additional options — see OpenAPI, TypeScript, Zod.
Option Precedence
Options resolve in this order (highest priority last):
- API default (
key_formatfrom API definition) - Export config (
export :openapi do ... end) - Query parameters (override everything)
Apiwork::API.define '/api/v1' do
key_format :underscore # Default for all exports
export :openapi do
key_format :camel # Override for OpenAPI
end
end# Uses :camel (from export config)
curl /api/v1/.openapi
# Uses :kebab (query parameter overrides config)
curl /api/v1/.openapi?key_format=kebab
# Uses :underscore (API default, no export config)
curl /api/v1/.typescriptEndpoint Configuration
Endpoint behavior is controlled with the endpoint block:
export :openapi do
endpoint do
mode :always
path '/openapi.json'
end
end| Mode | Behavior |
|---|---|
:auto | Development only (default) |
:always | Always mount endpoint |
:never | Never mount endpoint (rake/code only) |
Rake Tasks
Exports are generated to files with a rake task:
rake apiwork:export:write OUTPUT=public/exportsThis generates declared exports for all APIs:
public/exports/
├── api/
│ └── v1/
│ ├── openapi.json
│ ├── typescript.ts
│ └── zod.tsOptions
| Option | Description | Example |
|---|---|---|
OUTPUT | Output path (required) | public/exports |
API_PATH | Generate for specific API only | /api/v1 |
EXPORT_NAME | Generate specific format only | openapi |
KEY_FORMAT | Transform keys | camel |
LOCALE | Use specific locale | sv |
# Only OpenAPI for /api/v1
rake apiwork:export:write API_PATH=/api/v1 EXPORT_NAME=openapi OUTPUT=public/exports
# With camelCase keys
rake apiwork:export:write EXPORT_NAME=typescript KEY_FORMAT=camel OUTPUT=public/exportsCleaning Generated Files
rake apiwork:export:clean OUTPUT=public/exportsProgrammatic
For custom workflows, generate exports in code:
content = Apiwork::Export.generate(:openapi, '/api/v1')
content = Apiwork::Export.generate(:openapi, '/api/v1', format: :yaml)
content = Apiwork::Export.generate(:typescript, '/api/v1', key_format: :camel)Production
Endpoints generate on each request, which is slow for production traffic.
Exports are generated at build time (recommended):
rake apiwork:export:write OUTPUT=public/exportsThe static files are served from a CDN or web server.
Endpoints can be disabled entirely:
export :openapi do
endpoint do
mode :never
end
endIf you need runtime endpoints in production, consider caching at the HTTP level (Rack middleware, reverse proxy, or CDN).
See also
- Custom Exports — building custom export formats
- Export reference — programmatic generation API