Joakim Bugge
Joakim Bugge

Reputation: 393

Generate Swagger documentation as JSON/YAML in NestJS

I've followed the instructions to create a Swagger documentation, and my documentation is now available using Swagger UI. I'd like to also generate the documentation as JSON or YAML so it's easy to import in e.g. Postman, but I can't find any suitable methods in the SwaggerModule, nor does the Swagger UI have any export button.

Upvotes: 29

Views: 32283

Answers (9)

laszlo-horvath
laszlo-horvath

Reputation: 2129

Update in 2024:

I used the js-yaml package to convert the generated OpenAPI JS object to OpenAPI Yaml.

Here is the main part of the code:

import { writeFileSync } from 'fs';
import * as yaml from 'js-yaml';
import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';

async function generate(): Promise<void> {
    const app = await NestFactory.create(ApiModule);
    app.enableVersioning();

    const options = new DocumentBuilder()
      .setTitle('Your Application API')
      .setDescription('Your Application API')
      .setVersion('1.0.0')
      .addBearerAuth({ type: 'http', bearerFormat: 'JWT' })
      .build();

    const document = SwaggerModule.createDocument(app, options);
    const yamlDocument = yaml.dump(document);

    writeFileSync('swagger.yaml', yamlDocument);
    console.log('✅ OpenAPI YAML file generated as swagger.yaml.');
}

generate();

Please note: the generated YAML file is not perfect, so make sure to review it manually. For example in my case, it generated invalid tags.

Upvotes: 0

Stas Ridl S
Stas Ridl S

Reputation: 11

You can modify url of the json by settings jsonDocumentUrl property like this:

const config = new DocumentBuilder()
    .setTitle('App')
    .build();
const document = SwaggerModule.createDocument(app, config);     
SwaggerModule.setup('swagger', app, document, {
        jsonDocumentUrl: 'swagger.json',
      });

Get UI

GET http://{host}:{port}/swagger

Get JSON

GET http://{host}:{port}/swagger.json

For yaml their is

yamlDocumentUrl

Upvotes: 1

Ondřej Wagenknecht
Ondřej Wagenknecht

Reputation: 209

I need generate open API json file without database, webserver etc. dependency that's my app has. So I wrote another main.ts file (actualy I named it main-generate-swagger.ts). This main-generate-swagger.ts file is for json file generation only. No run it on production!

main-generate-swagger.ts:

import { NestFactory } from '@nestjs/core';
import fs from 'fs/promises';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { AppModule } from './app/app.module';
    
async function bootstrap() {
   const app = await NestFactory.create(
      AppModule,
      { preview: true, abortOnError: false } // <-- This parameters prevent for instantiate controllers but its not necessary for SwaggerModule
   );
    
    const prefix = 'api/v1';
    const corsOrigin = '*';
    
    app.enableCors({ origin: corsOrigin });
    app.setGlobalPrefix(prefix);
    
    const config = new DocumentBuilder().setTitle('Title').setDescription('Description').setVersion('1.0').addBearerAuth().build();
    const document = SwaggerModule.createDocument(app, config);
    
    await fs.writeFile('path/to/create/swagger.json', JSON.stringify(document));
    process.exit();
}
    
bootstrap();

Now instead of running main.ts file I run my new main-generate-swagger.ts. It generates json file and quit.

Notes:

  • How to configure app to start with main-generate-swagger.ts instead main.ts depends on environment. I use nx.dev so I change it in project.json.

Upvotes: 2

TameBadger
TameBadger

Reputation: 1590

With the latest version (v8 as of writing) of NestJS, following the setup in the openapi documentation, you should be able to access the json document without any extra setup with

GET http://{host}:{port}/api-docs

Upvotes: 0

Andre Possebom Garcia
Andre Possebom Garcia

Reputation: 21

Tested in Nestjs v8

GET http://{host}:{port}/docs

Get JSON

GET http://{host}:{port}/docs/json

Upvotes: 0

Suhail Akhtar
Suhail Akhtar

Reputation: 2023

Tested in Nestjs v9

Suppose the docs path is as follows

http://localhost:3000/docs

Get JSON

http://localhost:3000/docs-json

Get YAML

http://localhost:3000/docs-yaml

Upvotes: 31

chrismclarke
chrismclarke

Reputation: 2105

As well as the solution shown to write to disk (https://stackoverflow.com/a/51736406/5693245), you can still access on your own API endpoint.

As per docs, depending on whether you use swagger-ui-express or fastify to serve docs the location will be different

To generate and download a Swagger JSON file, navigate to http://localhost:3000/api-json (swagger-ui-express) or http://localhost:3000/api/json (fastify-swagger) in your browser (assuming that your Swagger documentation is available under http://localhost:3000/api).

It also depends on where you serve your API from, and assumes you use /api. If this is not the case replace with your endpoint, or in case you are not using a base URL for swagger-ui-express this would be http://localhost:3000/-json

Upvotes: 1

JobaerAhamed
JobaerAhamed

Reputation: 164

Try visiting /api/json instead of /api-json if you followed https://docs.nestjs.com/recipes/swagger.

Upvotes: 14

Kim Kern
Kim Kern

Reputation: 60357

According to this github issue you can just stringify the created Swagger document and e.g. write it to the file system like this:

const app = await NestFactory.create(ApplicationModule);
const options = new DocumentBuilder()
    .setTitle("Title")
    .setDescription("description")
    .setVersion("1.0")
    .build();
const document = SwaggerModule.createDocument(app, options);

fs.writeFileSync("./swagger-spec.json", JSON.stringify(document));
SwaggerModule.setup("/api", app, document);

await app.listen(80);

Upvotes: 35

Related Questions