Nest.jsのSwaggerが3.0（OpenAPI）に対応するぞ！！！

AngularライクなサーバーサイドフレームワークであるNest.jsですが、その中のnestjs/swaggerパッケージがついにOpenAPIに対応するようです。

まだプレビュー版ですが、試してみようと思います。

(2019/12/09追記)
正式版がリリースされていますので、[リファレンス](https://docs.nestjs.com/recipes/swagger)をご覧下さい。



# Issue

[next] Major release notes & plans
https://github.com/nestjs/swagger/issues/191

# nestjs/swaggerのバージョンを上げる

バージョンアップの方法は[こちらのコメント](https://github.com/nestjs/swagger/issues/191#issuecomment-547932991)で記載されているので、これを参考に入れてみます。

- まずはNest.jsのプロジェクトを生成します

```
nest new nestjs-swagger-test
cd nestjs-swagger-test
```

- `@next`を指定して`@nestjs/swagger`をインストールします

```
npm install --save @nestjs/swagger@next
```

※nestjs/swaggerを初めて導入する場合は`swagger-ui-express`のインストールも忘れずに([参考](https://docs.nestjs.com/recipes/swagger#installation))


- `@nestjs/common`,`@nestjs/core`の最新版を入れます

```
npm install @nestjs/common@latest @nestjs/core@latest
```

- typescriptの最新版を入れます

```
npm install typescript@latest
```

# コードの修正

main.tsはとりあえず、[リファレンス](https://docs.nestjs.com/recipes/swagger#bootstrap)通りに修正します

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

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

    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();
```

※DocumetBuilderのsetXxxやaddXxx系の関数が増えたり、減ったりしてるみたいです([参考](https://github.com/nestjs/swagger/pull/355#issuecomment-547925879))

>
 DocumentBuilder breaking changes (aka updated methods signatures):
addTag
addBearerAuth
addOAuth2
setContactEmail -> setContact (the entire contact information object)
setHost has been removed
setSchemes has been removed

>
The following methods have been added:
addServer
addApiKey
addBasicAuth
addSecurity
addSecurityRequirements

```src/app.controller.ts
import { Controller, Get, Post, Body } from '@nestjs/common';
import { AppService } from './app.service';
import { ApiOperation, ApiProperty, ApiBody } from '@nestjs/swagger';

class TestDto {
    @ApiProperty()
    message: string;
}

@Controller()
export class AppController {
    constructor(private readonly appService: AppService) { }

    @Get()
    @ApiOperation({ summary: 'hello' })
    getHello(): string {
        return this.appService.getHello();
    }

    @Post()
    @ApiOperation({ summary: 'post hello' })
    @ApiBody({ type: TestDto, description: 'test body' })
    postHello(@Body() body: TestDto) {
        return body;
    }
}
```

アノテーションが変わってます([参考](https://github.com/nestjs/swagger/pull/355#issuecomment-547925879))
>
The following decorators have been changed:
@ApiModelProperty -> @ApiProperty
@ApiModelPropertyOptional -> @ApiPropertyOptional
@ApiResponseModelProperty -> @ApiResponseProperty
@ApiImplicitQuery -> @ApiQuery
@ApiImplicitParam -> @ApiParam
@ApiImplicitBody -> @ApiBody
@ApiImplicitHeader -> @ApiHeader
@ApiOperation({ title: 'test' }) ->@ApiOperation({ summary: 'test' })

# 動かしてみる

- `npm start`で起動させます
- `http://{host}:3000/api`にアクセスします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325108/9b6787f7-10ab-f986-b15e-038e37cf471e.png)


# 最後に

無事に動きました！
ちゃんと「OAS3」が表示されているので、OpenAPIフォーマットになっているようです。
/api-jsonで出力してみてもちゃんと`openapi: 3.0.0`となっていました。

今回は簡単に動かしただけですが、他にも色々変更点を触ってみたいと思います。