Adonis Open Swagger

Generate API Schema

Generate OpenAPI schema for your Client

Generate TypeScript types from your OpenAPI documentation for end-to-end type safety. Use openapi-typescript to automatically create type-safe API clients that stay in sync with your backend.

What is API Schema Generation?

API schema generation converts your OpenAPI documentation into TypeScript types. This enables:

  1. End-to-End Type Safety: Frontend and backend share the same types
  2. Autocomplete: Get intelligent code completion for API requests and responses
  3. Compile-Time Errors: Catch API mismatches before runtime
  4. Zero Manual Typing: Types update automatically when your API changes

With Adonis Open Swagger generating OpenAPI docs and openapi-typescript generating types, you get a fully type-safe development workflow.


Prerequisites

Before generating API schema, ensure:

  1. ✅ Your AdonisJS server is running (typically on http://localhost:3333)
  2. ✅ Adonis Open Swagger is configured and generating documentation
  3. ✅ Your API endpoints are decorated with Swagger decorators
  4. ✅ OpenAPI JSON is accessible at /docs/json (default endpoint)

Generating Types

Use openapi-typescript to generate TypeScript types from your OpenAPI documentation:

bunx openapi-typescript http://localhost:3333/docs/json -o ./app/types/api-schema.ts

Command Breakdown

  • openapi-typescript: The CLI tool that generates TypeScript types
  • http://localhost:3333/docs/json: Your OpenAPI JSON endpoint
  • -o ./app/types/api-schema.ts: Output file path for generated types

Using Generated Types

Once generated, import and use the types in your frontend application:

OpenAPI Fetch

Use with popular API client libraries for even better DX:

frontend/api/client.ts
import createClient from "openapi-fetch";
import type { paths } from "./types/api-schema";

// Create type-safe client
const client = createClient<paths>({
  baseUrl: "http://localhost:3333",
});

// Fully typed requests and responses
const { data, error } = await client.GET("/users/{id}", {
  params: { path: { id: "123" } },
});

const { data: newUser } = await client.POST("/users", {
  body: {
    full_name: "John Doe",
    email: "john@example.com",
    password: "secure123",
  },
});

Automation

Add to package.json Scripts

Automate type generation by adding a script to your package.json:

package.json
{
  "scripts": {
    "generate:types": "openapi-typescript http://localhost:3333/docs/json -o ./app/types/api-schema.ts",
    "dev": "npm run generate:types && next dev"
  }
}

Now run:

npm run generate:types

Watch Mode for Development

Regenerate types automatically when your API changes:

package.json
{
  "scripts": {
    "generate:types:watch": "nodemon --watch 'app/**/*.ts' --exec 'npm run generate:types'"
  }
}

CI/CD Integration

Add type generation to your CI/CD pipeline:

.github/workflows/ci.yml
- name: Start API server
  run: npm run dev &

- name: Wait for server
  run: npx wait-on http://localhost:3333/docs/json

- name: Generate API types
  run: npm run generate:types

- name: Type check
  run: npm run type-check

Advanced Options

Custom Configuration

Create an openapi-ts.config.ts file for advanced configuration:

openapi-ts.config.ts
import { defineConfig } from "@hey-api/openapi-ts";

export default defineConfig({
  input: "http://localhost:3333/docs/json",
  output: "./app/types/api-schema.ts",
  client: "fetch",
  schemas: true,
  services: true,
});

Multiple Environments

Generate types for different environments:

package.json
{
  "scripts": {
    "generate:types:dev": "openapi-typescript http://localhost:3333/docs/json -o ./types/api-schema.ts",
    "generate:types:staging": "openapi-typescript https://staging.api.com/docs/json -o ./types/api-schema.ts",
    "generate:types:prod": "openapi-typescript https://api.com/docs/json -o ./types/api-schema.ts"
  }
}

Best Practices

1. Version Control Generated Types

Do commit generated types to version control:

# ❌ Don't ignore generated types
# app/types/api-schema.ts

Why? Team members can use types immediately without running the generator.

2. Regenerate After API Changes

Always regenerate types after modifying:

  • Controller methods
  • Swagger decorators
  • Request/response schemas
  • Route definitions

3. Use Type Guards

Add runtime validation for extra safety:

import type { paths } from "./types/api-schema";

type User =
  paths["/users/{id}"]["get"]["responses"]["200"]["content"]["application/json"];

function isUser(data: unknown): data is User {
  return (
    typeof data === "object" && data !== null && "id" in data && "email" in data
  );
}

4. Organize Types

Create type aliases for commonly used types:

types/api.ts
import type { paths } from "./api-schema";

// Reusable type aliases
export type User =
  paths["/users/{id}"]["get"]["responses"]["200"]["content"]["application/json"];
export type CreateUserRequest =
  paths["/users"]["post"]["requestBody"]["content"]["application/json"];
export type UpdateUserRequest =
  paths["/users/{id}"]["put"]["requestBody"]["content"]["application/json"];

5. Handle Errors Gracefully

Type error responses too:

type ErrorResponse =
  paths["/users/{id}"]["get"]["responses"]["404"]["content"]["application/json"];

async function getUser(id: string): Promise<User | ErrorResponse> {
  const response = await fetch(`/api/users/${id}`);

  if (!response.ok) {
    return (await response.json()) as ErrorResponse;
  }

  return (await response.json()) as User;
}

Troubleshooting

Server Not Running

Error: Failed to fetch http://localhost:3333/docs/json

Solution: Ensure your AdonisJS server is running:

node ace serve --watch

Invalid OpenAPI Schema

Error: OpenAPI schema validation failed

Solution: Check your Swagger decorators and schemas are correctly defined. Visit http://localhost:3333/docs to see if documentation renders properly.

Types Not Updating

Problem: Generated types don't reflect recent API changes

Solution:

  1. Restart your AdonisJS server
  2. Clear any caches
  3. Regenerate types: npm run generate:types
  4. Restart your TypeScript server in your IDE

Path Not Found

Error: Cannot find module './types/api-schema'

Solution: Ensure the output path in your generation command matches your import path:

# If importing from './types/api-schema'
bunx openapi-typescript http://localhost:3333/docs/json -o ./types/api-schema.ts

Last updated on