GraphQLのMutationのビジネスロジックのエラーはどうハンドリングすればいいのか
最近調査していた内容のメモ。
GraphQLのJSONレスポンスは data
と errors
の2つのキーに内容が大別される。
基本的に、期待するレスポンスが返せないときは errors
にエラー内容が入るというのがGraphQLでやろうとしていることだが、特にMutationにおけるビジネスロジックのエラーはどう記述すればいいだろうか。
恐らくFacebook的には「ダメです!」とエラーダイアログを表示させて終了なのかもしれないが、世の中のサービスが全部それに倣っているということはなく、エラーとなった要素をクライアント側で特定して赤くしたりエラー文言を添えたりしたい、なんてケースはよくある。自分の担当しているサービスもそんな感じだ。
ひとまずRelayのドキュメントを開いてみる→ Mutations · Relay
ざっくりと「レスポンスには(追加・削除含め)変更のあったTypeのオブジェクトを返せ」という風に僕は読んでいる。エラーについては特に記述はなく、 GraphQLのレスポンスとしての errors
に全て委ねているようだ。
RelayだけがGraphQLのプロトコルではないので(強力ではあるが)、他にないかと自分が軽く調べてみた限り、大きく2つの方法があるらしい。
1. errors
のデータ構造を拡張する
にその一例がある。確かに、という気持ちはあるが、今自分の使っているPerl版GraphQLライブラリはパラメータがかなり厳密に定められているので、そこに手を入れるとなるとモンキーパッチが必須になる。本家にpr送っても通るイメージが湧かない。パス。
だと、ライブラリのエラーオブジェクト自体を差し替えるというアイディアもある。が、これもPerl版GraphQLライブラリだと errors
に入れられるのは GraphQL::Error
オブジェクトが要素となる配列しか認められてないので、上記と同様のコメントになる。
2. data
側のレスポンスの型としてビジネスロジックでのエラーを返せるようにする
結論が出ないままcloseされていて悲しみしか感じない。が、このissueを参照する形で
Rust版GraphQLライブラリでのやりとりを見つけた。 data.<mutation>.errors
なら自分で専用の型を作ればいいだけなので、僕が見てきた方法の中ではこれが一番穏当で現実的なプランに見える。
もうちょっと調べてみたら、Ruby版GraphQLライブラリのドキュメントでも同様の内容があった→GraphQL - Mutations
が、これだと独自のレスポンス形式になるので、この取り決めがサービス内全体で適用できればいいが、Relayからはかなり逸脱しているようにも見える。その点の注意は必要そうだ。
まとめ
現時点だと、自分の担当サービスもビジネスロジックのエラーは data.<mutation>.errors
を入れる方向で進めようとしている。Relayを踏襲するかどうかは実は検討中。