concatで結合していた'.graphql'をGraphQL Code GeneratorのSchema ASTに任せた

はじめに

私は GraphQL Schema を記述する .graphql ( .gql ) を分割管理しています。 また、GraphQL Code Generator で TS 向けに型を出力して、型安全生活を送っています。

# ディレクトリ構造の例
$ tree . -L 2
.
├── codegen.yml
├── dis
│   └── schema.graphql # `src/*.graphql`が統合されたファイル
├── package.json
├── src
│   ├── category.graphql
│   ├── main.graphql
│   ├── post.graphql
│   └── tag.graphql
├── tsconfig.json
└── yarn.lock

分割方式は有用だと考えているのですが、一点だけ悩みがありました。 分割された .graphql をどう統合するかです。 そこで、今回は .graphql をどう統合するかの私的な改善を備忘録しておきます。

tl; dr

GraphQL Code Generator の Schema AST という plugin を使えば、.graphql を統合できます。 当たり前の当たり前ですが、これに気がつくのに時間がかかりました emoji-sweat_drops

yarn add -D @graphql-codegen/schema-ast
# 公式例
schema:
  - "./src/schema.graphql"
generates:
  path/to/file.graphql:
    plugins:
      - schema-ast
    config:
      includeDirectives: true

なぜ分割管理してるの?

  • 単一ファイルで膨れ上がる Schema を管理するのが単純に辛い
  • GraphQL Code Generator で特定の .graphql を選別して読み込みたい時がある

分割しているために筆者が困っていたこと

.graphql を分割しているのだから、それを統合してあげる必要があります。

そして、今までこの統合処理を package.json のスクリプト配下に自前で書いていました。 concat という package で src 配下の *.gqldist/schema.gql に統合出力していました。

{
  "scripts": {
    "build:concat": "mkdir dist && concat -o dist/schema.gql src/*.gql"
  }
}

たいした処理でもないので気にする必要はないかと思いましたが、以下の観点で改善したいと考えていました。

  • *.graphql を統合するためだけに、concat という package を管理する必要がある
  • 特定の *.graphql は混ぜたくないと考えると、とたんにコマンドが複雑化してしんどくなる

    • 私的なモノレポ構成だと Schema を共有管理しているため、A のバックエンドに含めたくない Schema だが、B のバックエンドには必要などのケースがありました

どうしたのか?

そもそも GraphQL Code Generator で .graphql を統合できないのか?が純粋に浮かびました。 調べると、Schema AST という plugin があるではないですか、同 plugin なら schema を統合できます。

This plugin prints the merged schema as string. If multiple schemas are provided, they will be merged and printed as one schema. Schema AST より

上述のディレクトリ構成とコマンドを鑑みると以下のように変更して解決しました。

ただし、Schema AST で統合できるのは .graphql の拡張子のみです。 .gql では統合できなかったので、リネームしました。

# codegen.yml
generates:
  dist/schema.graphql:
    schema:
      - src/**/*.graphql
    plugins:
      - schema-ast
// graohql-codegenで`dist/schema.graphql`に出力される
{
  "scripts": {
    "build:generate": "graphql-codegen --config codegen.yml"
  }
}

おわりに

今回はこの Schema AST を使って .graphql を統合した方が楽ですよ話でした、以上、ありゃっした!!

なのですが、なぜこんな単純な解決があるのに、ややこしい方法に至ったか自分で自分が不思議でなりません emoji-full_moon_with_face


Canji

クラウド周りをちょこまかしたい注意散漫人間。個人開発を楽しんでいたあの頃。