Open4

【Golang × Next.js】スキーマ駆動開発

kobokobo

モチベーション

Next.jsでフロントを作り、Golangでバックエンドを作っている。
この時、問題になってくるのが通信部分。

バックエンドもTypeScriptで書いているのであれば、tRPCという選択肢もあるが、なにせ、2024年現在、大規模なバックエンドをTypeScriptで表現するというのは結構難しい(賛否あると思うが、エラーハンドリングの難しさや構造的型付けによる、値オブジェクトの作りにくさ等により、結構工夫が必要だったりする)

なので、この通信部分を技術的な観点からうまくやってやろう。という話。

どんなことをするか

Next.jsはfetchを拡張し、独自のキャッシュ機構を作成している都合上、Next.js wayに乗りたければRESTFulなAPIを作成するのが得策な気がしている。
なので、今回は、OpenAPIを用い、スキーマ駆動で開発できるようにする。

  1. OpenAPIのスキーマを作成する
  2. 1からGolang側のViewModelを作成(うまくできそうなら、Handlerぐらいまで作成してくれるとありがたい)
  3. 1からNext.jsで用いることができる型情報のついたfetchクライアントを作成する
  4. 1からJestから用いることができる型情報のついたモックを作成する
kobokobo

1. OpenAPIのスキーマを作成する

とりあえずSignInするためのスキーマを作ってみる

openapi.yaml
openapi: 3.0.3

info:
  title: Asobiba OpenAPI - Golang × Next
  version: 0.1.0

paths:
  /api/sign-in:
    post:
      tags:
        - auth
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/sign-in-request'
      responses:
        '200':
          description: 正常系
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/sign-in-response'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/sign-in-bad-request'

components:
  schemas:
    sign-in-request:
      description: sign-in時のリクエストパラメータ
      type: object
      properties:
        email:
          type: string
        password:
          type: string
      required:
        - email
        - password
    sign-in-response:
      description: sign-in時のレスポンス
      type: object
      properties:
        access_token:
          type: string
        refresh_token:
          type: string
      required:
        - access_token
        - refresh_token
    sign-in-bad-request:
      description: sign-in時のBad Request
      type: object
      properties:
        error_code:
          type: string
kobokobo

2. 1からGolangのViewModelを作成する