21
15

More than 3 years have passed since last update.

Swaggerファイルを自動生成する

Posted at

はじめに

Swagger形式のOASを自動生成してくれるパッケージは無いか探していたところ、、、
TSOAという良さげなやつを見つけたので試してみました!

本記事で紹介する技術は以下になります。

  • TSOA
  • Node.js
  • TypeScript
  • express
  • swagger

作業環境

OS: Windows 10 Pro
Node: 12.1.0
npm: 6.9.0 

準備

Node+TypeScriptの環境を構築します。

PS C:\Users\user\Desktop\> mkdir project; cd project;
PS C:\Users\user\Desktop\project> npm init -y 
PS C:\Users\user\Desktop\project> npm install -D typescript @types/node ts-node
PS C:\Users\user\Desktop\project> ./node_modules/.bin/tsc --init

tsconfig.jsonの設定

今回、デコレータ、importでJSONの読み込みを行うので下記のように設定にしました。

tsconfig.json
{
  "compilerOptions": {
    // importでJSON読み込み用
    "moduleResolution": "node",
    "resolveJsonModule": true,
    // デコレータ用
    "experimentalDecorators": true,
    // 初期のまま
    "target": "es5",
    "module": "commonjs", 
    "strict": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true
  }
}

package.jsonの設定

ts-nodeをnpmスクリプトで実行できるようにpackage.jsonを書き換えます。

package.json
  "scripts": {
    "ts-node": "ts-node"
  }

簡易的なAPIを作ってみる

プロジェクトにTSOAをNPMでインストールします。

PS C:\Users\user\Desktop\project> npm install tsoa --save

今回は下記のような単純なAPIを用意します。

  • GETでリクエストされたユーザIDからユーザ情報を取得するAPI
  • POSTでリクエストされた情報でユーザ情報を登録するAPI

まずは、APIのエンドポイントとなるControllerを作成します。

PS C:\Users\user\Desktop\project> vi /controllers/usersController.ts
/controllers/usersController.ts
import { Body, Controller, Get, Header, Path, Post, Query, Route, SuccessResponse } from 'tsoa'
import { User, RequestBody } from '../models/user'
import { getUser, createUser } from '../services/userService';

@Route('users')
export class UsersController extends Controller {
  // IDをPATHに含めたGETなAPIを定義
  @Get('/get/{id}')
  public getUser(id: number): User {
    return getUser(id)
  }
  // POSTなAPI
  @Post('/create')
  public createUser(@Body() requestBody: RequestBody): string {
    createUser(requestBody)
    return 'success'
  }
}

続いて、ユーザ情報の型定義となるModelを作成します。

PS C:\Users\user\Desktop\project> vi /models/user.ts
/models/user.ts
// 「id」と「name」をプロパティに持つUser情報の型定義
export interface User {
  id: number
  name: string
}
// 「name」をプロパティに持つリクエスト情報の型定義
export interface RequestBody {
  name: string
}

最後に、API側で処理を行う部分となるServiceを作成します。

PS C:\Users\user\Desktop\project> vi /services/userService.ts
/services/userService.ts
import { User, RequestBody } from '../models/user'

// ※Databaseとかに下記のようなデータ格納されているとする
const users: Array<User> = [
  {
    id: 1,
    name: 'Tanka'
  },
  {
    id: 2,
    name: 'Suzuki'
  }
]

// IDでユーザ情報を取得する関数
export const getUser = (id: number): User => {
  return users.find((user) => user.id === id) || {}
}
// リクエストされた情報からユーザ情報を登録する関数
export const createUser = (body: RequestBody): void => {
  users.push({
    id: users.length + 1,
    name: body.name
  })
}

簡易的なAPIの作成が完了しました。

続いて、Swagger.jsonとルーティングファイルを自動生成するプログラムの作成に取り掛かります。

自動生成プログラムの作成

プロジェクト直下に下記のような自動生成用プログラムを用意しましょう。

PS C:\Users\user\Desktop\project> vi /generate.ts
/generate.ts
import { generateRoutes, generateSwaggerSpec, RoutesConfig, SwaggerConfig } from 'tsoa'

(async () => {
  // 自動生成するSwagger.jsonの設定を定義
  const swaggerOptions: SwaggerConfig = {
    basePath: '/api',
    entryFile: './api/server.ts',
    specVersion: 3,
    outputDirectory: './api/dist',
    controllerPathGlobs: ['./controllers/*Controller.ts'],
  }
  // 自動生成するルーティングファイルの設定を定義
  const routeOptions: RoutesConfig = {
    basePath: '/api',
    entryFile: './api/server.ts',
    routesDir: './api',
  }
  // 自動生成の実行
  await generateSwaggerSpec(swaggerOptions, routeOptions)
  await generateRoutes(routeOptions, swaggerOptions)
})();

ここまでの作成が終わったらプロジェクトのディレクトリ構成は以下のような感じになっているのではないでしょうか。
1.png

では、実際に自動生成を行いたいと思います。

自動生成を行う

下記のコマンドを実行します。

PS C:\Users\user\Desktop\project> npm run ts-node generate.ts

すると、無事にSwagger.jsonとルーティングファイルが自動生成されました。
20191120103750.png

生成したファイルを使ってみる

実際に生成されたファイルを使ってみます。
expressを使ってAPIサーバを立ち上げて、自動生成されたルーティングファイルを使ってみましょう。
ついてに、swagger-ui-expressを使って、自動生成されたSwagger.jsonからSwaggerUI画面を立ち上げてみましょう。

PS C:\Users\user\Desktop\project> npm install --save express @types/express
PS C:\Users\user\Desktop\project> npm install --save swagger-ui-express @types/swagger-ui-express
PS C:\Users\user\Desktop\project> vi /api/server.ts
/api/server.ts
import express from 'express'
import { RegisterRoutes } from './routes'
import '../controllers/usersController'

import swaggerUi from 'swagger-ui-express'
import swaggerDocument from './dist/swagger.json'

// ユーザリクエストの解析等
const app = express()
app.use(express.json())
app.use(express.urlencoded({ extended: true }))

// ルーティングファイルの登録
RegisterRoutes(app)

// Swagger UIの登録
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument))

// サーバ起動
app.listen(3000, () => {
 console.log('App running at http://localhost:3000')
})

サーバの準備ができたら起動しましょう。

PS C:\Users\user\Desktop\project> npm run ts-node api/server.ts
App running at http://localhost:3000

CurlでAPIを叩いてみます。

# 「Satou」さんを登録してみる
$ curl -X POST "http://localhost:3000/api/users/create" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"name\"
:\"Satou\"}"
"success"
# 「Satou」さんを取得してみる
$ curl -X GET http://localhost:3000/api/users/get/3 -H "accept: application/json"
{"id":3,"name":"Satou"}

無事に、ユーザの登録/取得が出来ました。

http://localhost:3000/api-docs/にアクセスしてSwaggerUIの画面も確認してみましょう。
3.png

無事に、SwaggerUIの立ち上げも出来ました。

以上、TSOAを使ってみたでした!

21
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
15