🍺
Node.js + fastify4 + TypeScript + SwaggerでRESTサーバを構築する
概要
Node.js、fastify4、TypeScript、Swaggerで簡単なサンプルを作ってみたので共有します。
サンプルコード: https://github.com/swmokyun/sample-fastify4-typescript-swagger
目的
- とにかくラクにRESTサーバを作りたい
- pythonでもいいけどフロントエンドでNext.jsとかつかうからNode.jsで言語を統一したい
- TypeScriptで型の恩恵を受けたい
- SwaggerでRESTスキーマまわりのあれこれをラクしたい
expressよりfastifyがいいらしい
Node.jsでサーバといえばexpressと思ってたけど、最近ではKoa.jsとかfastifyが有力候補らしい。fastifyの方がtypescriptまわりがいい感じにサポートされているっぽいのでこっちをチョイス。
fastify-swaggerがいい感じ
調べた感じではfastify-swaggerを使うとtypescriptで型補完しながらスキーマ定義が記述できるっぽい。これは素晴らしい。
typeboxでさらにいい感じ
typeboxを使うとfastifyでスキーマ定義と関数の型を共通化できる。これはさらに素晴らしい。
サンプル
公式を参考にGETやqueryのサンプルを追加したのが以下になります。
また、各モジュールのバージョンは以下になっています。fastifyはバージョンがあがると結構APIが変わるっぽいので注意。
"@fastify/swagger": "^8.2.1",
"@fastify/swagger-ui": "^1.3.0",
"@sinclair/typebox": "^0.25.16",
"fastify": "^4.10.2"
import { Static, Type } from "@sinclair/typebox"
import Fastify from "fastify"
const runFastify = async () => {
const fastify = Fastify({
logger: true,
})
await fastify.register(require("@fastify/swagger"))
await fastify.register(require("@fastify/swagger-ui"), {
routePrefix: "/documentation",
staticCSP: true,
transformSpecificationClone: true,
})
/**
* test_post
*/
const User = Type.Object({
name: Type.String(),
mail: Type.Optional(Type.String({ format: "email" })),
})
type UserType = Static<typeof User>
fastify.post<{ Body: UserType; Reply: UserType }>(
"/test_post",
{
schema: {
body: User,
response: {
200: User,
},
},
},
(req, rep) => {
const { body: user } = req
rep.status(200).send(user)
}
)
/**
* test get, querystring
*/
const ErrorResponse = Type.Object({
msg: Type.String(),
})
type ErrorResponseType = Static<typeof ErrorResponse>
fastify.get<{ Querystring: UserType; Reply: UserType | ErrorResponseType }>(
"/test_get",
{
schema: {
querystring: User,
response: {
200: User,
400: ErrorResponse,
},
},
},
(req, rep) => {
const { query: user } = req
if (user.name.length < 3) {
rep.status(400).send({ msg: "name is too short" })
} else {
rep.status(200).send(user)
}
}
)
/**
* start fastify
*/
await fastify.ready()
fastify.listen({ port: 3000 }, function (err, address) {
if (err) {
fastify.log.error(err)
process.exit(1)
}
})
}
runFastify()
http://localhost:3000/documentation でSwaggerからAPIの確認やJSONスキーマの出力が可能。とっても便利で開発が捗ります。
Discussion