こんにちは!バクラク事業部の@ysakura_です。バクラクビジネスカードを担当しています。
先日、GraphQLのMutationから引数(InputのField)を削りました。その際、ダウンタイムを発生させない様に複数回に分けてリリースを行いました。GraphQLでのNullの扱いに少し苦労をしたので、その知見を共有出来ればと思います。
この記事は、LayerX Tech Advent Calendar 2022 8日目の記事です。
動作環境
担当するプロダクトでは、GraphQLのライブラリとしてBE(バックエンド)では gqlgen、FE(フロントエンド)では Apollo Client を (React + TypeScript) の構成で用いています。 また、GraphQLのスキーマはバックエンドのレポジトリで管理しています。
サンプルスキーマ
Mutationの引数のInputからFieldを削ります。(参考: Mutations and Input Types)
例えば、下記のGraphQLにおいて UserInput
から email
を削る事を考えます
input UserInput { name: String! email: String! } type Mutation { createUser(input: UserInput!): User updateUser(id: ID!, input: UserInput!): User }
段階的なリリース
下記の順番で、複数回に分けてリリースをしていきます。
基本的には、FEでFieldの送信を止める
→スキーマからFieldを削る
という流れですが、FEからの送信を止めた段階でエラーとならない様、BEの修正を先に行います。
BE: NullableなFieldに変更する
Non-NullなFieldでは、FEからの送信を止めた段階でBEでエラーが出ます。
※ (エラーの例) "必須なフィールド(email)が存在しません"
そのため、先にNullable(Optional)なFieldに変更します。下記の様に、ビックリマーク(!
)を無くせば良いです。
input UserInput { name: String! email: String }
Nullableにするので、Nullに対応したコードに修正する必要があります。
BE: Fieldの保存をやめる
最終的にスキーマからFieldを削るので、BEで対象のFieldの保存を止める必要があります。
次のリリースでFEからのFieldの送信を止めるので、BEではNullが入る様になります。
誤作動しない様に、このタイミングでBEでの保存を止めるのが良いでしょう。こちらは前述の変更と同じタイミングでのリリースが可能です。
FE: Fieldの送信を止める
スキーマから対象のFieldを削った状態で、FEからそのFieldを送るとBEでエラーが出ます。
※ (エラーの例) "emailというFieldは存在しません"
そのため、先にFEからの送信を止めます。
今回のApollo Clientのケースでは、 email
を指定しない もしくは undefined
を指定する事で送信を止められます。Null
を指定すると、NullableなFieldゆえ Null
が送られてしまうので注意が必要です。ここに気づくのに苦労しました。
参考: GraphQL の引数では「値を入れない」と「null を渡す」を区別できる
BE: スキーマからFieldを削る
最後に、GraphQLのスキーマから対象のFieldを削ります。合わせて、BEでコードの自動生成を行います。
今回の例では UserInput
から email
を削ります。
input UserInput { name: String! } type Mutation { createUser(input: UserInput!): User updateUser(id: ID!, input: UserInput!): User }
FE: 最新のスキーマを反映する
FEでもスキーマを反映します。
既に、FEでは送らない / BEでは保存しない状態になっているので、このスキーマ反映はBEとFEで順不同です。自分のチームでは既存のデプロイフローに従い、BE → FEの順でデプロイしました。
以上により段階的な移行が実現できます。
まとめ
GraphQLのMutationから引数(InputのField)をダウンタイムなしに削る方法についてご紹介しました。MutationのInputからFieldを削る際には、ケアする事が少し多いです。 この順序を間違えると、FEで保存が出来なくなったり、BEで想定外の値が保存されたりします。また Nullの扱いにも注意が必要です。
明日以降の LayerX Tech Advent Calendar 2022 の記事もお楽しみください!