🍖
Node.js環境で、PythonのFastAPIみたいなOpenAPIドキュメント自動生成を求めて、Fastifyに手を出してみる
やりたかったこと
Node.jsでAPIを書いたら、OpenAPIドキュメントを自動生成して欲しい
背景
APIを書く場合に使うFrameworkにおいてPythonではDjangoやFlaskが有名ですが、最近注目されているFrameworkにFastAPIというものがあります。FastAPIは、動作がNode.js並に早いとか習得が容易といった特徴もありますが、コードを書くと自動でOpenAPIドキュメントを作ってくれてwebインターフェースも用意してくれる機能がとても便利です。
詳しくは知りたい方は、ドキュメントを読んでください。
同じことがNode.jsで作ったAPIでもできないかなーと思って調べてみました。
Fastify使ったらできた
Fastify + fastify-swaggerでできました。
適当に作ったサンプル
やったこと
導入
fastifyとfastify-swaggerをインストール
npm i fastify
npm i fastify-swagger
最低限の実装
とりあえず動くように書く
import * as fastify from 'fastify'
import fastifySwagger from 'fastify-swagger'
const server: fastify.FastifyInstance = fastify.fastify({ logger: true })
server.register(fastifySwagger, {
routePrefix: '/docs',
openapi: {},
exposeRoute: true,
})
server.get('/ping', async (request, reply) => {
return { pong: 'it worked!' }
})
server.listen(3000)
起動して、ブラウザから http://127.0.0.1:3000/docs にアクセスしたら動いた。
クエリパラメータを渡せるようにしてみる
queryとresponseのschemaを定義して、指定してあげる。
TSの型定義でハマった。とりあえず動くようにはした。正しい書き方を知りたい。
// queryとresponseのschemaを定義する
const schema1: fastify.RouteShorthandOptions = {
schema: {
querystring: {
type: 'object',
properties: {
test_query: {
type: 'number',
},
},
},
response: {
200: {
type: 'object',
properties: {
test_response: {
type: 'number'
},
},
},
},
},
}
// デフォルトだとqueryのTSとしての型定義がunknownなので、定義してあげる
interface Request1 extends fastify.RequestGenericInterface {
Querystring: {
test_query: number
}
}
server.get<Request1, unknown, fastify.FastifySchema>('/querytest', schema1, async (request, reply) => {
return { test_response: request.query.test_query }
})
動いた
パスパラメータを渡せるようにしてみる
クエリパラメータとほぼ同じ
// paramsとresponseのschemaを定義する
const schema2: fastify.RouteShorthandOptions = {
schema: {
params: {
type: 'object',
properties: {
test_param: {
type: 'string',
},
},
},
response: {
200: {
type: 'object',
properties: {
test_response2: {
type: 'string'
},
},
},
},
},
}
// デフォルトだとParamsのTSとしての型定義がunknownなので、定義してあげる
interface Request2 extends fastify.RequestGenericInterface {
Params: {
test_param: string
}
}
server.get<Request2, unknown, fastify.FastifySchema>('/paramstest/:test_param', schema2, async (request, reply) => {
return { test_response2: request.params.test_param }
})
動いた
所感
- 結構いい感じに使えそう。想定通りOpenAPIドキュメントを自動生成してくれる。
- Fastifyはexpressに使い勝手が近いのでとっつきやすいが、expressと比べるとマイナーなので情報が少ないのがツラい。特にTSの型がツラい。いい書き方が分からんのでサンプルが欲しいが、公式ドキュメントは基本JS。
- Fastifyのschema定義とTSの型定義で同じことを2重に書いてる。無駄に感じる。型定義はTSの世界で完結させたい。
- そういう意味だと、NestJSを使うのがいいのかもしれない。
Discussion