1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

一休.comAdvent Calendar 2024

Day 2

GraphQLスキーマを出力時に上書きする

Last updated at Posted at 2024-12-01

この記事は一休.com Advent Calendar 2024 2日目の記事です。

概要

GraphQLアプリケーションにおいて、ランタイムに影響を与えずに型定義のみ上書きしたいケースがあり、出力時に力業でスキーマを上書きすることによって解決したという事例を紹介します。

構成

  • スキーマビルダー(バックエンド): Pothos
  • クライアント(フロントエンド): Relay

問題

schema.graphql
type RestaurantGroup {
  customers(after: ID, first: Int): CustomerConnection!
}

上記のフィールドを例として説明します。
first は取得件数を表す引数で、メインのユースケースではRelayが想定するように 20 などを指定してページネーションに利用しています。
一方、(本当はよくないのですが便宜上)使用する場所によっては first に大きな数字を与えることで全件取得の普通のリストとしても使っていました。しかし、first はnullableなため、全件取得するつもりが指定を忘れてデフォルトの件数しか取得していないことによるバグがときどき発生していました。
そこで、first をnon-nullableに変更してlintで指定忘れを防ぐことを考えました。その際、古いクライアントでエラーが出ないようにランタイムの振る舞いは保持したいという要件もあったので、リゾルバのコードは変更せずスキーマファイル出力時にのみ first の型を上書きすることにしました。

解決方法

手動でASTをいじることも覚悟していましたが、幸い graphql-tools というライブラリの mapSchema という便利な関数のおかげで簡単にスキーマの編集ができました。
この関数は公式ドキュメントに示されている型から読み取れるように、スキーマに対してさまざまな操作が可能です。
今回は firsttype を上書きするだけなので下記のように書きました。

build_schema.ts
/* ビルド時に実行するスクリプト */
import { writeFileSync } from 'node:fs'

import { MapperKind, mapSchema } from '@graphql-tools/utils'
import { GraphQLInt, GraphQLNonNull, printSchema } from 'graphql'

import { builder } from './graphql.js'

// ビルダーからスキーマオブジェクトを生成
const schema = builder.toSchema()

// 編集
const modifiedSchema = mapSchema(schema, {
  [MapperKind.OBJECT_FIELD]: (fieldConfig) =>
    fieldConfig.args && 'first' in fieldConfig.args ?
      {
        ...fieldConfig,
        args: {
          ...fieldConfig.args,
          first: {
            ...fieldConfig.args.first,
            type: new GraphQLNonNull(GraphQLInt),
          },
        },
      }
    : fieldConfig,
})

// ファイルに出力
writeFileSync('schema.graphql', printSchema(modifiedSchema))

出力したスキーマファイルにもしっかり反映されていました。

schema.graphql
type RestaurantGroup {
  customers(after: ID, first: Int!): CustomerConnection!
}

参考

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?