0
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Node.js + fastify + TypeScript + SwaggerでRESTサーバを構築する

Posted at

概要

Node.js、fastify、TypeScript、Swaggerで簡単なサンプルを作ってみたので共有します。
サンプルコード: https://github.com/swmokyun/sample-fastify-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で型補完しながらスキーマ定義が記述できるっぽい。これは素晴らしい。
https://github.com/fastify/fastify-swagger

typeboxでさらにいい感じ

typeboxを使うとfastifyでスキーマ定義と関数の型を共通化できる。これはさらに素晴らしい。
https://www.fastify.io/docs/latest/TypeScript/#json-schema

サンプル

公式を参考にGETやqueryのサンプルを追加したのが以下になります。
また、各モジュールのバージョンは以下になっています。fastifyはバージョンがあがると結構APIが変わるっぽいので注意。

"@sinclair/typebox": "^0.23.1",
"fastify": "^3.24.1",
"fastify-swagger": "^4.12.6"
import { Static, Type } from "@sinclair/typebox"
import fastify, { FastifyInstance } from "fastify"
import fastifySwagger from "fastify-swagger"

const PORT = 9000

const server: FastifyInstance = fastify({ logger: true })

/**
 * swagger
 */
server.register(fastifySwagger, {
  routePrefix: "/docs",
  swagger: {
    info: {
      title: "Test swagger",
      description: "Testing the Fastify swagger API",
      version: "0.1.0",
    },
  },
  exposeRoute: true,
})

/**
 * test_post
 * https://www.fastify.io/docs/latest/TypeScript/#typebox
 */
const User = Type.Object({
  name: Type.String(),
  mail: Type.Optional(Type.String({ format: "email" })),
})
type UserType = Static<typeof User>

server.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>

server.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)
    }
  }
)

server.listen(PORT)

http://localhost:9000/docs 
でSwaggerからAPIの確認やJSONスキーマの出力が可能。とっても便利で開発が捗ります。

0
4
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
0
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?