Open API
Installation
Much like the other packages, @ts-rest/open-api
is easy to download, also note if you want to serve a Swagger UI you'll want to download swagger-ui-express
for express, or @nestjs/swagger
for Nest.
- npm
- yarn
- pnpm
npm install @ts-rest/open-api
yarn add @ts-rest/open-api
pnpm add @ts-rest/open-api
Generating a OpenAPI Document
import { myContract } from './my-api';
import { generateOpenApi } from '@ts-rest/open-api';
const openApiDocument = generateOpenApi(myContract, {
info: {
title: 'Posts API',
version: '1.0.0',
},
});
No kidding, that's it 🥳 You can now serve this document however you want, use it for CodeGen for your non-TS clients, or use it to generate a Swagger UI!
Our OpenAPI generator uses @anatine/zod-openapi
to generate open-api docs for your Zod schemas, so make sure to use Zod everywhere on your API to get the best experience.
Serving a Swagger UI
In Express use swagger-ui-express
:
import { myContract } from './my-api';
import { generateOpenApi } from '@ts-rest/open-api';
import * as swaggerUi from 'swagger-ui-express';
const openApiDocument = generateOpenApi(myContract, {
info: {
title: 'Posts API',
version: '1.0.0',
},
});
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(openApiDocument));
In NestJS use @nestjs/swagger
:
import { myContract } from './my-api';
import { generateOpenApi } from '@ts-rest/open-api';
import { NestFactory } from '@nestjs/core';
import { SwaggerModule } from '@nestjs/swagger';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const document = generateOpenApi(myContract, {
info: {
title: 'Posts API',
version: '1.0.0',
},
});
SwaggerModule.setup('api', app, document);
// ^ Path for swagger
await app.listen(3000);
}
bootstrap();
Don't worry if you don't use express or Nest, whatever library you want to use is OK our OpenAPI returns a plain JSON object which is fully compliant with the OpenAPI spec.
Enabling operationId
's (Recommended!)
If your contract has unique names for all of your endpoints, you can enable operationId
's by setting setOperationId
to true
in the options:
const openApiSchema = generateOpenApi(
postsApi,
{
info: {
title: 'Posts API',
version: '1.0.0',
},
},
{
setOperationId: true,
}
);
Below is an example of what the OpenAPI document would look like with operationId
's enabled:
{
"openapi": "3.0.2",
"paths": {
"/posts": {
"get": {
"description": "Get all posts",
"tags": [],
"parameters": [
{
"name": "userId",
"in": "query",
"schema": {
"type": "number"
}
}
],
"operationId": "getPosts", // <--- This is the operationId
"responses": {
JSON Query Params
If you've enabled JSON Query params for your server and client, you can enable jsonQuery
to mark the query params as application/json
in the OpenAPI document:
const openApiSchema = generateOpenApi(
postsApi,
{
info: {
title: 'Posts API',
version: '1.0.0',
},
},
{
jsonQuery: true,
}
);
You'll want to do this to let your non ts-rest clients know that they should send the query params as JSON.