Next.js + サーバーサイドTypeScript + 関数フレーバーでクリーンなアプリを作ったので実装意図とか書く Advent Calendar 2022
の13日目。株式会社mofmofに生息しているshwldです。
前日はGraphQLサーバーを構成する要素について書きました
GraphQLサーバーを構成する要素
┣━┳━ modules
┃ ┗━┳━ account // Entityなどに対応するオブジェクト単位でディレクトリをきっている
┃ ┣━┳━ mutation-resolvers
┃ ┃ ┗━┳━ account.create // アクションイベントごとにディレクトリを切る
┃ ┃ ┣━━━ create-account-validation.ts // バリデーションに関するロジック
┃ ┃ ┣━━━ create-account.sdl.graphql // このアクションのスキーマ定義
┃ ┃ ┣━━━ create-account.test.ts // テストロジック
┃ ┃ ┣━━━ create-account.ts // mutation本体
┃ ┃ ┗━━━ index.ts
┃ ┣━┳━ object-resolvers
┃ ┃ ┗━┳━ account // オブジェクトごとにディレクトリを切る
┃ ┃ ┣━━━ account.sdl.graphql // オブジェクトのスキーマ定義
┃ ┃ ┣━━━ account.ts // Entityをオブジェクトに変換するロジック
┃ ┃ ┗━━━ index.ts
┃ ┣━┳━ query-resolvers
┃ ┃ ┗━━━ .gitkeep // root queryはめったに生やさないので空なことが多いです
┃ ┗━ index.ts
┣━ middlewares // GraphQL Shieldなどを格納する場所
/use-cases/graphql-resolvers/src/modules
GraphQL Modulesと同じようにmoduleを分けて管理しています。
考慮ポイント
テストを処理の隣に置く
テストだけを切ってテストだけを配置するか、フロントでよくある形である実処理の隣に置くかで悩むところですが、後者を選択しました。
処理を治す場合テストも一緒に直すし、逆も然りなので、個人的にはこっちのほうが開発体験がいいです。
ここ一番悩んだところで、レイヤー的観点で見るとテストだけを別プロジェクトにしたかった気持ちもあったのですが、開発体験を優先しました。
なのでその苦渋の選択の結果として、GraphQLリゾルバの層にはテストに使う依存が含まれてしまっている(devDependenciesなので許してという気持ちで入れた)というモヤりポイントがあります。
スキーマ定義を一箇所にまとめるか散らすか
type AccountEdge implements Edge {
node: Account
cursor: String
}
type AccountConnection implements Connection {
pageInfo: PageInfo
edges: [AccountEdge]
}
type Account implements Node {
id: ID!
createdAt: DateTime!
updatedAt: DateTime!
isDeleted: Boolean
name: String!
projects: ProjectConnection!
}
スキーマ定義はこういうやつです。
現状は、各モジュールの各要素の中に散らばって存在しています。
GraphQLリゾルバの作り方としてはスキーマファーストを選択しているのですが、これは割りとコードファーストに近いアプローチだなーと感じてます。
(モジュールを切って、要素を定義して初めてスキーマを決められる)
ただここは、後述(このカレンダー内の別記事で書く予定)のplopjsによるコード生成により、yarn g:module
コマンド一発でこのディレクトリ構造とファイルを一発で作成できるため、局所的なスキーマ定義によるコードファースト的なメリットを維持しつつスキーマファーストの恩恵を得られる構成になってると思います(何書いてるかよくわからなくなってきたけど伝わるでしょうか...)
次回予告
明日はRelay Styleページネーションについて書きます