> For the complete documentation index, see [llms.txt](https://jakekwak.gitbook.io/nestjs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jakekwak.gitbook.io/nestjs/recipes/untitled-4.md).

# OpenAPI (Swagger)

## OpenAPI (Swagger)

### This chapter applies only to TypeScript

[OpenAPI](https://swagger.io/specification/) (Swagger) 사양은 RESTful API를 설명하는 강력한 정의 형식입니다. Nest는 전용 [모듈](https://github.com/nestjs/swagger)을 제공합니다.

## Installation

먼저 필요한 패키지를 설치해야합니다.

```bash
$ npm install --save @nestjs/swagger swagger-ui-express
```

fastify를 사용하는 경우 `swagger-ui-express` 대신 `fastify-swagger`를 설치해야합니다.

```bash
$ npm install --save @nestjs/swagger fastify-swagger
```

## Bootstrap

설치 프로세스가 완료되면 부트 스트랩 파일 (대부분 `main.ts`)을 열고 `SwaggerModule` 클래스를 사용하여 Swagger를 초기화 하십시오.

```typescript
import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { ApplicationModule } from './app.module';

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

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

  await app.listen(3000);
}
bootstrap();
```

`DocumentBuilder`는 `SwaggerModule`의 기본 문서를 구성하는 데 도움을 주는 헬퍼 클래스입니다. 제목, 설명, 버전 등과 같은 속성을 설정할 수있는 몇가지 방법이 포함되어 있습니다.

정의된 HTTP 경로로 전체 문서를 만들려면 `SwaggerModule` 클래스의 `createDocument()`메소드를 사용하십시오. 이 메소드는 각각 응용 프로그램 인스턴스와 기본 Swagger 옵션의 두가지 인수를 사용합니다.

마지막 단계는 `setup()`을 호출하는 것입니다. **(1)** Swagger를 장착하는 경로, **(2)** 응용 프로그램 인스턴스, **(3)** Nest 애플리케이션을 설명하는 문서를 순차적으로 허용합니다.

이제 다음 명령을 실행하여 HTTP 서버를 시작할 수 있습니다.

```bash
$ npm run start
```

응용 프로그램이 실행되는 동안 브라우저를 열고 `http://localhost:3000/api`로 이동하십시오. 비슷한 페이지가 나타납니다.

&#x20;`SwaggerModule`은 모든 엔드 포인트를 자동으로 반영합니다. 백그라운드에서는 `swagger-ui-express`를 사용하고 라이브 문서를 만듭니다.

> info **힌트** 해당 Swagger JSON 파일을 다운로드하려면 브라우저에서`http://localhost:3000/api-json`을 호출하면됩니다 (Swagger 설명서가 `http://localhost:3000/api`에 게시된 경우). ).

## Body, query, path parameters

정의된 컨트롤러를 검사하는 동안 `SwaggerModule`은 경로 핸들러에서 사용된 `@Body()`, `@Query()` 및 `@Param()`데코레이터를 모두 찾습니다. 따라서 유효한 문서를 만들 수 있습니다.

또한 이 모듈은 리플렉션을 활용하여 **모델 정의**를 만듭니다. 다음 코드를 살펴보십시오.

```typescript
@Post()
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

> warning **알림** 본문 정의를 암시적으로 설정하려면 `@ApiImplicitBody()` 데코레이터 (`@nestjs/swagger` 패키지)를 사용할 수 있습니다.

`CreateCatDto`를 기반으로 모듈 정의가 생성됩니다 :

&#x20;보시다시피 클래스에 선언된 속성이 몇 개 있지만 정의가 비어 있습니다. 클래스 속성이 `SwaggerModule`에 액세스할 수 있도록 하려면, `@ApiModelProperty()` 데코레이터로 모든 속성을 표시해야 합니다.

```typescript
import { ApiModelProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiModelProperty()
  readonly name: string;

  @ApiModelProperty()
  readonly age: number;

  @ApiModelProperty()
  readonly breed: string;
}
```

브라우저를 열고 생성 된 `CreateCatDto` 모델을 확인하십시오 :

&#x20;`@ApiModelProperty()` 데코레이터는 옵션 객체를 받습니다 :

```typescript
export const ApiModelProperty: (metadata?: {
  description?: string;
  required?: boolean;
  type?: any;
  isArray?: boolean;
  collectionFormat?: string;
  default?: any;
  enum?: SwaggerEnumType;
  format?: string;
  multipleOf?: number;
  maximum?: number;
  exclusiveMaximum?: number;
  minimum?: number;
  exclusiveMinimum?: number;
  maxLength?: number;
  minLength?: number;
  pattern?: string;
  maxItems?: number;
  minItems?: number;
  uniqueItems?: boolean;
  maxProperties?: number;
  minProperties?: number;
  readOnly?: boolean;
  xml?: any;
  example?: any;
}) => PropertyDecorator;
```

> warning **힌트** `{{"@ApiModelProperty({ required: false })"}}`를 계속 입력하지 않도록 하는`@ApiModelPropertyOptional()`단축 데코레이터가 있습니다.

덕분에 **default** 값을 간단히 설정하고 속성이 필요한지 여부를 결정하거나 유형을 명시적으로 설정할 수 있습니다.

## Multiple specifications

Swagger 모듈은 또한 여러 사양을 지원하는 방법을 제공합니다. 즉, 엔드 포인트마다 다른 `SwaggerUI`를 사용하여 다른 문서를 제공할 수 있습니다.

`SwaggerModule`이 다중 사양을 지원할 수 있도록 하려면 응용 프로그램을 모듈 방식으로 작성해야 합니다. `createDocument()`메소드는 세 번째 인수인 `extraOptions`를 사용합니다. `extraOptions`는 `include` 속성이 모듈 배열을 필요로 하는 객체입니다.

아래와 같이 다중 사양 지원을 설정할 수 있습니다.

```typescript
import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { ApplicationModule } from './app.module';

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

  /**
   * createDocument(application, configurationOptions, extraOptions);
   *
   * createDocument method takes in an optional 3rd argument "extraOptions"
   * which is an object with "include" property where you can pass an Array
   * of Modules that you want to include in that Swagger Specification
   * E.g: CatsModule and DogsModule will have two separate Swagger Specifications which
   * will be exposed on two different SwaggerUI with two different endpoints.
   */

  const options = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();

  const catDocument = SwaggerModule.createDocument(app, options, {
    include: [CatsModule],
  });
  SwaggerModule.setup('api/cats', app, catDocument);

  const secondOptions = new DocumentBuilder()
    .setTitle('Dogs example')
    .setDescription('The dogs API description')
    .setVersion('1.0')
    .addTag('dogs')
    .build();

  const dogDocument = SwaggerModule.createDocument(app, secondOptions, {
    include: [DogsModule],
  });
  SwaggerModule.setup('api/dogs', app, dogDocument);

  await app.listen(3000);
}
bootstrap();
```

이제 다음 명령으로 서버를 시작할 수 있습니다.

```bash
$ npm run start
```

Cat의 SwaggerUI를 보려면 `http://localhost:3000/api/cats`로 이동하십시오.

&#x20;`http://localhost:3000/api/dogs`는 강아지를위한 SwaggerUI를 노출시킵니다:

> warning **알림** `DocumentBuilder`로 **SwaggerOptions**를 생성하고 새로 생성 된 `options`에 대해 `createDocument()`를 실행한 다음 두 번째 **SwaggerOptions**에 대한 작업을 시작하기 전에 `setup()`을 사용하여 즉시 "제공"해야 합니다. 두 번째 Swagger 사양의 경우. 이 특정 순서는 Swagger 구성이 다른 옵션으로 대체되지 않도록하기위한 것입니다.

## Working with enums

`SwaggerModule`이 `Enum`을 식별할 수 있으려면, `@ApiModelProperty`의 `enum` 속성을 값 배열로 수동으로 설정해야 합니다.

```typescript
@ApiModelProperty({ enum: ['Admin', 'Moderator', 'User']})
role: UserRole;
```

`UserRole` 열거형은 다음과 같이 정의할 수 있습니다.

```typescript
export enum UserRole {
  Admin = 'Admin',
  Moderator = 'Moderator',
  User = 'User',
}
```

> warning **Note** The above usage can only be applied to a **property** as part of a **model definition.**

Enums can be used by itself with the `@Query()` parameter decorator in combination with the `@ApiImplicitQuery()` decorator.

```typescript
@ApiImplicitQuery({ name: 'role', enum: ['Admin', 'Moderator', 'User'] })
async filterByRole(@Query('role') role: UserRole = UserRole.User) {
  // role returns: UserRole.Admin, UserRole.Moderator OR UserRole.User
}
```

> warning **힌트** `enum`과 `isArray`는 `@ApiImplicitQuery()`와 함께 사용할 수 있습니다

`isArray`를 **true**로 설정하면 `enum`을 **multi-select**로 선택할 수 있습니다.

## Working with arrays

속성이 실제로 배열일 때 유형을 수동으로 표시해야 합니다.

```typescript
@ApiModelProperty({ type: [String] })
readonly names: string[];
```

위의 그림처럼 배열의 첫 번째 요소로 타입을 입력하거나 `isArray` 속성을 `true`로 설정하십시오.

## Tags

처음에는 `DocumentBuilder`를 사용하여 `cats` 태그를 만들었습니다. 지정된 태그에 컨트롤러를 연결하려면`@ApiUseTags(...tags)` 데코레이터를 사용해야합니다.

```typescript
@ApiUseTags('cats')
@Controller('cats')
export class CatsController {}
```

## Responses

커스텀 HTTP 응답을 정의하기 위해 `@ApiResponse()`데코레이터를 사용합니다.

```typescript
@Post()
@ApiResponse({ status: 201, description: 'The record has been successfully created.'})
@ApiResponse({ status: 403, description: 'Forbidden.'})
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

예외 필터 섹션에 정의된 일반적인 HTTP 예외와 마찬가지로 Nest는 핵심 `@ApiResponse` 데코레이터에서 상속되는 사용 가능한 **API 응답** 세트를 제공합니다.

* `@ApiOkResponse()`
* `@ApiCreatedResponse()`
* `@ApiBadRequestResponse()`
* `@ApiUnauthorizedResponse()`
* `@ApiNotFoundResponse()`
* `@ApiForbiddenResponse()`
* `@ApiMethodNotAllowedResponse()`
* `@ApiNotAcceptableResponse()`
* `@ApiRequestTimeoutResponse()`
* `@ApiConflictResponse()`
* `@ApiGoneResponse()`
* `@ApiPayloadTooLargeResponse()`
* `@ApiUnsupportedMediaTypeResponse()`
* `@ApiUnprocessableEntityResponse()`
* `@ApiInternalServerErrorResponse()`
* `@ApiNotImplementedResponse()`
* `@ApiBadGatewayResponse()`
* `@ApiServiceUnavailableResponse()`
* `@ApiGatewayTimeoutResponse()`

사용 가능한 HTTP 예외 외에도 Nest는 `HttpStatus.OK`, `HttpStatus.CREATED` 및 `HttpStatus.METHOD_NOT_ALLOWED`에 대한 단축 데코레이터를 제공합니다.

```typescript
@Post()
@ApiCreatedResponse({ description: 'The record has been successfully created.'})
@ApiForbiddenResponse({ description: 'Forbidden.'})
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

## Authentication

`DocumentBuilder` 클래스의 `addBearerAuth()` 메소드를 사용하여 베어러 인증을 활성화할 수 있습니다. 그런 다음 선택한 경로 또는 전체 컨트롤러를 제한하려면 `@ApiBearerAuth()`데코레이터를 사용하십시오.

```typescript
@ApiUseTags('cats')
@ApiBearerAuth()
@Controller('cats')
export class CatsController {}
```

OpenAPI 설명서는 다음과 같습니다.

## File upload

`@ApiImplicitFile` 데코레이터와 `@ApiConsumes()`를 사용하여 특정 메소드에 대한 파일 업로드를 활성화 할 수 있습니다. 다음은 [File Upload](https://app.gitbook.com/techniques/file-upload) 기술을 사용한 전체 예입니다.

```typescript
@UseInterceptors(FileInterceptor('file'))
@ApiConsumes('multipart/form-data')
@ApiImplicitFile({ name: 'file', required: true, description: 'List of cats' })
uploadFile(@UploadedFile() file) {}
```

## Decorators

사용 가능한 모든 OpenAPI 데코레이터에는 핵심 데코레이터와 명확하게 구분할 수있는 `Api`접두사가 있습니다. 아래는 정의된 사용 수준 (적용 가능한 경우)을 가진 엑스포트된 데코레이터의 전체 목록입니다.

|                               |                     |
| ----------------------------- | ------------------- |
| `@ApiOperation()`             | Method              |
| `@ApiResponse()`              | Method / Controller |
| `@ApiProduces()`              | Method / Controller |
| `@ApiConsumes()`              | Method / Controller |
| `@ApiBearerAuth()`            | Method / Controller |
| `@ApiOAuth2Auth()`            | Method / Controller |
| `@ApiImplicitBody()`          | Method              |
| `@ApiImplicitParam()`         | Method              |
| `@ApiImplicitQuery()`         | Method              |
| `@ApiImplicitHeader()`        | Method              |
| `@ApiImplicitFile()`          | Method              |
| `@ApiExcludeEndpoint()`       | Method              |
| `@ApiUseTags()`               | Method / Controller |
| `@ApiModelProperty()`         | Model               |
| `@ApiModelPropertyOptional()` | Model               |

실제 사례는 [여기](https://github.com/nestjs/nest/tree/master/sample/11-swagger)에서 확인할 수 있습니다.
