GraphQLのミューテーション:動く例で解説
GraphQLのミューテーション
GraphQLのミューテーション:構文、変数、入力型 | We.Inc
データを作成、更新、削除するGraphQLミューテーションを書きましょう。オペレーションの構文、$変数、入力オブジェクト型、返すべき値、そしてエラーや部分的な成功がどう見えるかを解説します。
GraphQLのミューテーションは、データを変更するために送るオペレーションです。mutationキーワードで始まり、スキーマのMutation型のフィールドを呼び出し、引数(通常は$変数に入れた1つの入力オブジェクト)を渡し、結果のどのフィールドを返すかを選択します。トップレベルのミューテーションのフィールドは、並列ではなく1つずつ順番に実行されます。
ミューテーション構文の各部分
- キーワードと名前
- mutation AddTask
- オペレーションが書き込みであることを示し、ログ用に名前を付ける
- 変数の定義
- ($input: TaskInput!)
- JSONとして別に送る、型付きの値を宣言する
- ルートフィールド
- addTask(input: $input)
- Mutation型に定義されたフィールド
- 選択セット
- { id title done }
- 返してほしい結果のフィールド
- 変数のJSON
- {"input": {...}}
- 実際の値。クエリ文字列には含めない
下のビルダーでは、小さなタスクリストを例に、完全なミューテーションを確認できます。オペレーション、コードが一緒に送る変数のJSON、そして典型的なレスポンスです。タスクのタイトルを入力すると変数が更新されるので、対応するスキーマに対してそのまま実行できるリクエストをコピーできます。
- 作成、更新、削除のいずれかを選びます。
- タスクのタイトルを入力します。入力に合わせて変数のJSONが更新されます。
- ミューテーションと変数をコピーし、1つのPOSTのqueryキーとvariablesキーとして送ります。
- サーバーからの返答を、その下に表示されるレスポンス例と比べます。
- 値はクエリ文字列に直接埋め込まず、変数で送りましょう。エスケープのバグを防げるうえ、サーバーがパース済みのドキュメントをキャッシュできます。
- IDを含め、変更されたオブジェクトを返しましょう。クライアントのキャッシュが、2回目のリクエストなしで画面を更新できます。
- すべてのオペレーションに名前を付けましょう。名前付きのミューテーションは、サーバーログやエラーレポートでずっと見つけやすくなります。
- 1つのミューテーションに含まれる複数のルートフィールドは、トランザクションではなく別々のステップとして扱いましょう。後のフィールドが失敗しても、前のフィールドの処理は完了したままです。
よくある質問
クエリとミューテーションの違いは何ですか?
どちらも同じ構文を使い、どちらもデータを返せます。慣例として、クエリは読み取りだけを行い、ミューテーションは書き込みを行います。実行のルールも異なり、クエリのフィールドは並列に解決されることがありますが、トップレベルのミューテーションのフィールドは直列に実行されます。
普通の引数ではなく入力型を使うのはなぜですか?
入力オブジェクトは、関連する値を1つの型付き引数にまとめます。そのため、ミューテーションのシグネチャが短く保たれ、後から省略可能なフィールドを追加しても、すべての呼び出し側を変更する必要がありません。
ミューテーションをGETリクエストで送れますか?
いいえ。GraphQL over HTTPのガイドラインでは、サーバーがGETを受け付けてよいのはクエリのオペレーションだけです。ミューテーションはPOSTで送ります。これにより、書き込みがブラウザーやCDNのキャッシュに入ることも防げます。
複数のフィールドを持つミューテーションはアトミックですか?
いいえ。graphql.orgでも、直列実行はデータベースのトランザクションではないと説明されています。2つ目のフィールドが失敗しても1つ目の変更は残り、レスポンスには一方のデータともう一方のエラーが含まれます。
削除のミューテーションは何を返すべきですか?
仕様では決められていませんが、フィールドには出力の型が必要です。よく使われるのは、削除したオブジェクトのID、削除したオブジェクトそのもの、またはIDと成功フラグを持つペイロード型です。
ミューテーションの構造
- サーバー側では、スキーマがMutation型を宣言し、そのフィールドがクライアントの呼び出せる書き込み操作になります。各フィールドには引数と戻り値の型があります。クライアント側では、オペレーションがそのフィールドを1つ以上指定し、引数を渡し、返してほしい結果のフィールドを選びます。
- フィールドがオブジェクト型を返す場合は、クエリと同じく選択セットが必須です。新しいIDと画面に表示するフィールドを要求しておけば、クライアントはレスポンスから直接表示を更新できます。
変数と入力オブジェクト
- 変数は、オペレーション名の後にドル記号と型を付けて宣言します。たとえば $input: TaskInput! です。感嘆符を付けると、その変数は必須になります。値は、リクエスト本文の別の変数オブジェクトに入れて送られます。
- 入力オブジェクト型は、typeではなくinputキーワードで宣言します。フィールドにはスカラー、列挙型、リスト、他の入力型しか使えないため、クライアントが送るデータの形を簡単に検証できます。
書き込みで起きるエラー
- フィールド名のつづり間違いや必須の変数の欠落など、ドキュメントが不正な場合、サーバーはデータなしでエラーを返し、何も書き込まれません。
- 実行中に書き込み自体が失敗した場合、そのフィールドはnullで返り、エラーの項目にメッセージとパスが入ります。多くのスキーマは、タイトルが長すぎるといった想定内の問題もペイロード型のフィールドとして返し、クライアントがフォームの横に表示できるようにしています。
例で使っているスキーマ
Mutation型と入力型
入力型にはinputキーワードを使います。TaskPatchには必須のフィールドがないので、更新では変わった部分だけを送れます。
JavaScriptから送る
fetchでミューテーションをPOSTする
ドキュメントと変数は、1つのJSON本文の2つのキーとして送られます。ステータスが200でもエラーを確認しましょう。
1つのオペレーションで2回書き込む
エイリアスを使うと、同じフィールドを2回実行できます。2つ目は1つ目が終わってから実行されますが、2つ目が失敗しても1つ目は取り消されません。
作成
入力型が新しいタスクのフィールドをまとめます。選択セットでは、サーバーが割り当てたIDを要求します。
更新
IDで変更するタスクを指定し、入力には変更するフィールドだけを入れます。
削除
削除したタスクには選択できるものが残らないので、このスキーマは削除したIDを単純なIDスカラーとして返します。
ミューテーションビルダー
ミューテーションを選ぶ
タスクのタイトル
ミューテーション
変数(JSON)
レスポンス例
ミューテーションをコピー
変数をコピー
削除にはIDだけが必要なので、タイトルは送信されません。
無料で始める · クレジットカード不要
関連: ガイド|Webマーケティングと集客を学ぶ
製品
ご利用いただける方
機能
リソース
会社情報
サイトマップを見る