taiyoh's memorandum

@ttaiyoh が、技術ネタで気づいたことを書き溜めておきます。

GraphQLのMutationのビジネスロジックのエラーはどうハンドリングすればいいのか

最近調査していた内容のメモ。

GraphQLのJSONレスポンスは dataerrors の2つのキーに内容が大別される。
基本的に、期待するレスポンスが返せないときは errors にエラー内容が入るというのがGraphQLでやろうとしていることだが、特にMutationにおけるビジネスロジックのエラーはどう記述すればいいだろうか。
恐らくFacebook的には「ダメです!」とエラーダイアログを表示させて終了なのかもしれないが、世の中のサービスが全部それに倣っているということはなく、エラーとなった要素をクライアント側で特定して赤くしたりエラー文言を添えたりしたい、なんてケースはよくある。自分の担当しているサービスもそんな感じだ。

ひとまずRelayのドキュメントを開いてみる→ Mutations · Relay

ざっくりと「レスポンスには(追加・削除含め)変更のあったTypeのオブジェクトを返せ」という風に僕は読んでいる。エラーについては特に記述はなく、 GraphQLのレスポンスとしての errors に全て委ねているようだ。

RelayだけがGraphQLのプロトコルではないので(強力ではあるが)、他にないかと自分が軽く調べてみた限り、大きく2つの方法があるらしい。

1. errors のデータ構造を拡張する

medium.com

にその一例がある。確かに、という気持ちはあるが、今自分の使っているPerl版GraphQLライブラリはパラメータがかなり厳密に定められているので、そこに手を入れるとなるとモンキーパッチが必須になる。本家にpr送っても通るイメージが湧かない。パス。

tech.eshaiju.in

だと、ライブラリのエラーオブジェクト自体を差し替えるというアイディアもある。が、これもPerl版GraphQLライブラリだと errors に入れられるのは GraphQL::Error オブジェクトが要素となる配列しか認められてないので、上記と同様のコメントになる。

2. data 側のレスポンスの型としてビジネスロジックでのエラーを返せるようにする

github.com

結論が出ないままcloseされていて悲しみしか感じない。が、このissueを参照する形で

github.com

Rust版GraphQLライブラリでのやりとりを見つけた。 data.<mutation>.errors なら自分で専用の型を作ればいいだけなので、僕が見てきた方法の中ではこれが一番穏当で現実的なプランに見える。
もうちょっと調べてみたら、Ruby版GraphQLライブラリのドキュメントでも同様の内容があった→GraphQL - Mutations
が、これだと独自のレスポンス形式になるので、この取り決めがサービス内全体で適用できればいいが、Relayからはかなり逸脱しているようにも見える。その点の注意は必要そうだ。

まとめ

現時点だと、自分の担当サービスもビジネスロジックのエラーは data.<mutation>.errors を入れる方向で進めようとしている。Relayを踏襲するかどうかは実は検討中。