Skip to content

Generate and Use an OpenAPI Client ​

5.x only

This page applies to the 5.x line only (npm 5.1.x, branch 5.x). From 6.0, @ahoo-wang/fetcher-generator lives in the Wow repository (typescript/) and is documented at wow.ahoo.me; its successor @ahoo-wang/wow-generator is on npm from Wow 9.2.0 (9.2.1 or later accepts fetcher 6).

Start with a checked-in document, generate into a dedicated directory, and compile a caller. This example produces a known class and method rather than assuming generated names.

1. Prepare a consumer project ​

bash
pnpm add @ahoo-wang/fetcher@^5.0.0 @ahoo-wang/fetcher-decorator@^5.0.0 \
  @ahoo-wang/fetcher-eventstream@^5.0.0 @ahoo-wang/fetcher-openapi@^5.0.0 \
  @ahoo-wang/fetcher-wow@^5.0.0
pnpm add -D @ahoo-wang/fetcher-generator@^5.0.0 typescript@6.0.3

Save this as tsconfig.json:

json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "experimentalDecorators": true,
    "strict": true,
    "skipLibCheck": true
  },
  "include": ["src/**/*.ts"]
}

2. Save the contract ​

Save the complete document below as openapi.json. The root tag, operation tag, operationId and 200 response schema give the generator enough information to create a typed ordinary API client.

json
{
  "openapi": "3.0.3",
  "info": {
    "title": "Items",
    "version": "1.0.0"
  },
  "tags": [
    {
      "name": "Items"
    }
  ],
  "paths": {
    "/items/{id}": {
      "get": {
        "operationId": "getItem",
        "tags": ["Items"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Item"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Item": {
        "type": "object",
        "required": ["id"],
        "properties": {
          "id": {
            "type": "string"
          }
        }
      }
    }
  }
}

3. Generate and compile ​

bash
pnpm exec fetcher-generator generate -i ./openapi.json -o ./src/generated -t ./tsconfig.json
pnpm exec tsc --noEmit -p ./tsconfig.json

For this exact document the output includes ItemsApiClient.ts, types.ts and index.ts. The client exposes getItem(id: string, httpRequest?: ParameterRequest, attributes?: Record<string, any>): Promise<Item>, and Item has a required string id. The generator also writes .fetcher-generator.json to record output ownership.

If optional fetcher-generator.config.json is absent, the CLI logs a configuration read error and continues. Add a config only when you need an override; see configuration precedence.

4. Write the caller outside generated files ​

Save this as src/loadItem.ts, then repeat the TypeScript check:

ts
import { Fetcher } from '@ahoo-wang/fetcher';
import { ItemsApiClient, type Item } from './generated';

export async function loadItem(baseURL: string): Promise<Item> {
  const client = new ItemsApiClient({ fetcher: new Fetcher({ baseURL }) });
  return client.getItem('42');
}

Calling loadItem(yourApiOrigin) requires an application server implementing GET /items/42, JSON {"id":"42"}, and any required authentication/CORS configuration. Generation and type checking do not make that remote request. Catch the returned promise at the application boundary.

For a local runtime check, mock fetch with Response.json({ id: '42' }), call the function, assert the final URL and returned ID, and restore fetch in finally.

5. Regenerate and review ​

Edit the source document and rerun the same command. Review changed models, method signatures and the ownership manifest before accepting the diff. Do not put application code into src/generated: files generated again at the same path are overwritten. Unchanged stale owned files can be deleted; modified stale files are preserved. Generation is not an atomic directory transaction, so inspect partial output after a failure.

Missing methods usually require checking tags and operation IDs; missing return types require checking the 200 response. A schema compiler is not a server validator. No runtime resource is allocated by this caller until it is invoked; the JSON response is consumed on success.

See CLI options, output and regeneration, OpenAPI documents, and the distinct Wow discovery rules.

apiClientGenerator.ts:73 implements ordinary client generation.

Review integration boundaries; return to this task group.

Released under the Apache License 2.0.