apigen-ts
Simple typed OpenAPI client generator
Features
- Generates ready to use
ApiClient
with types (using fetch
) - Single output file, minimal third-party code
- Loads schemas from JSON / YAML, locally and remote
- Ability to customize
fetch
with your custom function - Automatic formating with Prettier
- Can parse dates from date-time format (
--parse-dates
flag) - Support OpenAPI v2, v3, v3.1
- Can be used with npx as well
Install
yarn install -D apigen-ts
Usage
1. Generate
yarn apigen-ts https://petstore3.swagger.io/api/v3/openapi.json ./api-client.ts
yarn apigen-ts ./openapi.json ./api-client.ts
Run yarn apigen-ts --help
for more options. Examples of generated clients here.
2. Import
import { ApiClient } from "./api-client"
const api = new ApiClient({
baseUrl: "https://example.com/api",
headers: { Authorization: "secret-token" },
})
3. Use
await api.pet.getPetById(1)
await api.pet.findPetsByStatus({ status: "sold" })
await api.user.updateUser("username", { firstName: "John" })
Advanced
Login flow
const { token } = await api.auth.login({ usename, password })
api.Config.headers = { Authorization: token }
await api.protectedRoute.get()
Automatic date parsing
yarn apigen-ts ./openapi.json ./api-client.ts --parse-dates
const pet = await api.pet.getPetById(1)
const createdAt: Date = pet.createdAt
String union as enums
You can generate string literal union instead of native enums in case you want to run in Node.js environment with type-stripping. To achive this pass --inline-enums
command line argument or use inlineEnums: true
in Node.js API.
yarn apigen-ts ./openapi.json ./api-client.ts --inline-enums
This will generate:
type MyEnum = "OptionA" | "OptionB"
enum MyEnum = {
OptionA = "OptionA",
OptionB = "OptionB"
}
Errors handling
An exception will be thrown for all unsuccessful return codes.
try {
const pet = await api.pet.getPetById(404)
} catch (e) {
console.log(e)
}
Also you can define custom function to parse error:
class MyClient extends ApiClient {
async ParseError(rep: Response) {
return { code: "API_ERROR" }
}
}
try {
const api = new MyClient()
const pet = await api.pet.getPetById(404)
} catch (e) {
console.log(e)
}
Base url resolving
You can modify how the endpoint url is created. By default URL constructor used to resolve endpoint url like: new URL(path, baseUrl)
which has specific resolving rules. E.g.:
new URL("/v2/cats", "https://example.com/v1/") // -> https://example.com/v2/cats
new URL("v2/cats", "https://example.com/v1/") // -> https://example.com/v1/v2/cats
If you want to have custom endpoint url resolving rules, you can override PrepareFetchUrl
method. For more details see issue.
class MyClient extends ApiClient {
PrepareFetchUrl(path: string) {
return new URL(`${this.Config.baseUrl}/${path}`.replace(/\/{2,}/g, "/"))
}
}
const api = new MyClient({ baseUrl: "https://example.com/v1" })
const pet = await api.pet.getPetById(404)
Node.js API
Create file like apigen.mjs
with content:
import { apigen } from "apigen-ts"
await apigen({
source: "https://petstore3.swagger.io/api/v3/openapi.json",
output: "./api-client.ts",
name: "MyApiClient",
parseDates: true,
inlineEnums: false,
resolveName(ctx, op, proposal) {
if (proposal[0] === "users") return
const [a, b] = op.name.split("/").slice(3, 5)
return [a, `${op.method}_${b}`]
},
})
Then run with: node apigen.mjs
Usage with different backend frameworks
FastAPI
By default apigen-ts
generates noisy method names when used with FastAPI. This can be fixed by custom resolving for operations ids.
from fastapi import FastAPI
from fastapi.routing import APIRoute
app = FastAPI()
def update_operation_ids(app: FastAPI) -> None:
for route in app.routes:
if isinstance(route, APIRoute):
ns = route.tags[0] if route.tags else "general"
route.operation_id = f"{ns}_{route.name}".lower()
update_operation_ids(app)
Note: If you want FastAPI to be added as preset, open PR please.
Compare
Development