API Reference

openApiPlugin

Serve your OpenAPI document and an API reference UI for it, on any adapter.

Serve a reference UI for the OpenAPI document generated from your API, and the document itself if you want it public. Name it under plugins on defineConfig and api.mount serves its routes. See the OpenAPI guide.

pnpm add @kizunajs/openapi@beta
bun add @kizunajs/openapi@beta
npm install @kizunajs/openapi@beta
import { openApiPlugin } from '@kizunajs/openapi';

Parameters

openApiPlugin(props: OpenApiPluginProps): PluginDeclaration
ParameterTypeRequiredDescription
propsOpenApiPluginPropsYesEverything generateOpenApi takes, plus the options below

Props

OpenApiPluginProps extends GenerateOpenApiOptions, so info, servers, setOperationId and the rest work exactly as they do on generateOpenApi. On top of those:

OptionDefaultDescription
slug'openApi'What handlers reach this plugin under, and the key it installs at
docsPathoffThe reference UI. Give it a path to serve it
jsonPathoffThe document. A path ending in .json
yamlPathoffThe document as YAML. A path ending in .yaml
provider'scalar'Which reference UI to render, 'scalar' or 'swagger'
cdnUrlthe provider's CDNWhere to load the UI's assets from
pageTitlethe document titleThe page's <title>
configurationnoneExtra config merged into the UI's initializer

They are also the options generateOpenApi uses when you call it without any, so a build step and the served document cannot disagree.

Each path prop is off until you give it a path. The document paths carry their extension in the type, so jsonPath: '/docs' does not compile.

Example

kizuna.config.ts
import { defineConfig } from 'kizunajs';
import { expressAdapter } from '@kizunajs/express';
import { openApiPlugin } from '@kizunajs/openapi';
import { routes } from './src/routes';

export default defineConfig({
    adapter: expressAdapter(),
    routes,
    plugins: [
        openApiPlugin({
            info: {
                title: 'My API',
                version: '1.0.0',
            },
            docsPath: '/docs',
            setOperationId: true,
        }),
    ],
});
src/index.ts
import kizuna from '../kizuna.config';

kizuna.api.mount(app);

Two documents

slug is what a plugin installs at, so a second document gets its own:

kizuna.config.ts
plugins: [
    openApiPlugin({
        info: {
            title: 'My API',
            version: '1.0.0',
        },
        docsPath: '/docs',
    }),
    openApiPlugin({
        slug: 'internalDocs',
        info: {
            title: 'My API, internal',
            version: '1.0.0',
        },
        docsPath: '/internal/docs',
    }),
],

Plugin routes

These are plugin routes: they live outside api.routes, so your fetch client, the generated Swift and Kotlin clients, and the document itself never list them.

Public by default

Nothing guards these routes. Gate them with your framework's own middleware if your document should not be public.

Air-gapped and strict CSP

cdnUrl points the page at a self-hosted copy of the UI's assets. For 'scalar' it is the script URL; for 'swagger' it is the directory holding swagger-ui.css and swagger-ui-bundle.js.

Serving it yourself

generateOpenApi is exported, so you can skip the plugin and serve the document from your own route. Mixing works: leave a path unset and the plugin stays off it. Set jsonPath but not docsPath to serve the document while rendering your own UI.

On this page