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.
- pnpm
- npm
- yarn
pnpm add @ts-rest/open-api
npm install @ts-rest/open-api
yarn 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.