介绍 Introduction

导读

OpenAPI 规范是一种与语言无关的定义格式,用于描述 RESTful API。Nest 提供了一个专用的 模块,允许通过利用装饰器生成此类规范。

安装

要开始使用它,我们首先安装所需的依赖项。

bash
$ npm install --save @nestjs/swagger

Bootstrap

安装过程完成后,打开 main.ts 文件并使用 SwaggerModule 类初始化 Swagger:

main
ts
import { NestFactory } from '@nestjs/core'
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'
import { AppModule } from './app.module'

async function bootstrap() {
  const app = await NestFactory.create(AppModule)

  const config = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build()
  const document = SwaggerModule.createDocument(app, config)
  SwaggerModule.setup('api', app, document)

  await app.listen(3000)
}
bootstrap()
提示

document(由 SwaggerModule#createDocument() 方法返回)是符合 OpenAPI 文档 的可序列化对象。除了通过 HTTP 托管它,您还可以将其保存为 JSON/YAML 文件,并以不同的方式使用它。

DocumentBuilder 有助于构建符合 OpenAPI 规范的基本文档。它提供了几种方法,允许设置标题、说明、版本等属性。为了创建完整文档(定义了所有 HTTP 路由),我们使用 SwaggerModule 类的 createDocument() 方法。此方法接受两个参数,一个应用程序实例和一个 Swagger 选项对象。或者,我们可以提供第三个参数,该参数应为 SwaggerDocumentOptions 类型。有关此内容的更多信息,请参阅 文档选项部分

创建文档后,我们可以调用 setup() 方法。它接受:

  1. 安装 Swagger UI 的路径
  2. 应用程序实例
  3. 上面实例化的文档对象
  4. 可选配置参数(阅读更多 此处)

现在您可以运行以下命令来启动 HTTP 服务器:

bash
$ npm run start

在应用程序运行时,打开浏览器并导航到 http://localhost:3000/api。您应该会看到 Swagger UI。

img

如您所见,SwaggerModule 会自动反映您的所有端点。

提示

要生成并下载 Swagger JSON 文件,请导航至 http://localhost:3000/api-json(假设您的 Swagger 文档可在 http://localhost:3000/api 下找到)。

您还可以使用 @nestjs/swagger 中的设置方法在您选择的路由上公开它,如下所示:

ts
SwaggerModule.setup('swagger', app, document, {
  jsonDocumentUrl: 'swagger/json',
})

这将在 http://localhost:3000/swagger/json 上公开它

警告

使用 fastifyhelmet 时,CSP 可能存在问题,为了解决此冲突,请按如下所示配置 CSP:

ts
app.register(helmet, {
  contentSecurityPolicy: {
    directives: {
      defaultSrc: [`'self'`],
      styleSrc: [`'self'`, `'unsafe-inline'`],
      imgSrc: [`'self'`, 'data:', 'validator.swagger.io'],
      scriptSrc: [`'self'`, `https: 'unsafe-inline'`],
    },
  },
})
// 如果你根本不打算使用 CSP,你可以使用以下命令:
app.register(helmet, {
  contentSecurityPolicy: false,
})

文档选项

创建文档时,可以提供一些额外的选项来微调库的行为。这些选项应为SwaggerDocumentOptions类型,可以是以下内容:

ts
export interface SwaggerDocumentOptions {
  /**
   * 规范中要包含的模块列表
   */
  include?: Function[]

  /**
   * 应检查并包含在规范中的其他额外模型
   */
  extraModels?: Function[]

  /**
   * 如果为`true`,swagger 将忽略通过`setGlobalPrefix()`方法设置的全局前缀
   */
  ignoreGlobalPrefix?: boolean

  /**
   * 如果为`true`,swagger 还将从`include`模块导入的模块中加载路由
   */
  deepScanRoutes?: boolean

  /**
   * 自定义 operationIdFactory 将用于根据 `controllerKey` 和 `methodKey` 生成 `operationId`
   * @default () => controllerKey_methodKey
   */
  operationIdFactory?: (controllerKey: string, methodKey: string) => string
}

例如,如果您想确保库生成的操作名称像createUser而不是UserController_createUser,您可以设置以下内容:

ts
const options: SwaggerDocumentOptions = {
  operationIdFactory: (
    controllerKey: string,
    methodKey: string
  ) => methodKey
}
const document = SwaggerModule.createDocument(app, config, options)

设置选项

您可以通过传递满足 SwaggerCustomOptions 接口的选项对象作为 SwaggerModule#setup 方法的第四个参数来配置 Swagger UI。

ts
export interface SwaggerCustomOptions {
  /**
   * 如果为`true`,Swagger 资源路径将以通过`setGlobalPrefix()`设置的全局前缀作为前缀。
   * Default: `false`.
   * @see https://docs.nestjs.com/faq/global-prefix
   */
  useGlobalPrefix?: boolean

  /**
   * 如果为`false`,则仅提供 API 定义(JSON 和 YAML)(在`/{path}-json`和`/{path}-yaml`上)。
   * 如果您已经在其他地方托管 Swagger UI,并且只想提供 API 定义,这将特别有用。
   * Default: `true`.
   */
  swaggerUiEnabled?: boolean

  /**
   * URL 指向要在 Swagger UI 中加载的 API 定义。
   */
  swaggerUrl?: string

  /**
   * 要提供的 JSON API 定义的路径。
   * Default: `<path>-json`.
   */
  jsonDocumentUrl?: string

  /**
   * 要提供的 YAML API 定义的路径。
   * Default: `<path>-yaml`.
   */
  yamlDocumentUrl?: string

  /**
   * 钩子允许在提供服务之前更改 OpenAPI 文档。
   * 它在文档生成之后和作为 JSON 和 YAML 提供之前被调用。
   */
  patchDocumentOnRequest?: <TRequest = any, TResponse = any>(
    req: TRequest,
    res: TResponse,
    document: OpenAPIObject
  ) => OpenAPIObject

  /**
   * 如果为`true`,则 OpenAPI 定义的选择器将显示在 Swagger UI 界面中。
   * Default: `false`.
   */
  explorer?: boolean

  /**
   * 其他 Swagger UI 选项
   */
  swaggerOptions?: SwaggerUiOptions

  /**
   * 要在 Swagger UI 页面中注入的自定义 CSS 样式。
   */
  customCss?: string

  /**
   * 要在 Swagger UI 页面中加载的自定义 CSS 样式表的 URL。
   */
  customCssUrl?: string | string[]

  /**
   * 要在 Swagger UI 页面中加载的自定义 JavaScript 文件的 URL。
   */
  customJs?: string | string[]

  /**
   * 要在 Swagger UI 页面中加载的自定义 JavaScript 脚本。
   */
  customJsStr?: string | string[]

  /**
   * Swagger UI 页面的自定义图标。
   */
  customfavIcon?: string

  /**
   * Swagger UI 页面的自定义标题。
   */
  customSiteTitle?: string

  /**
   * 包含静态 Swagger UI 资产的文件系统路径(例如:./node_modules/swagger-ui-dist)。
   */
  customSwaggerUiPath?: string

  /**
   * @deprecated This property has no effect.
   */
  validatorUrl?: string

  /**
   * @deprecated This property has no effect.
   */
  url?: string

  /**
   * @deprecated This property has no effect.
   */
  urls?: Record<'url' | 'name', string>[]

}

示例

此处 提供了一个可用的示例。