本記事では「Spring BootでGraphQLを実装する」で使ったサンプルアプリを例に記述します。
Mutationのスキーマ定義
まずMutationの命名はアプリケーションと紐づく動詞が望ましいです。今回は、id、name、pageCountの3つを引数に取り戻り値はBook型のスキーマを定義してみます。
※この後の説明の都合上、nameフィールドは必須、それ以外は非必須となる引数としています。
※「!」の詳細は「GraphQLのスキーマと型定義のエクスクラメーションマークの意味」を参照ください。
type Mutation {
registerBook (
id: ID
name: String!
pageCount: Int
): Book
}
サーバーサイド
サーバーサイドの実装は以下の通りです。GraphQLMutationResolverをimplementsする必要があります(Javaで実装しているためこのようにしています、他の言語では違った形になるかと思います)。また、スキーマ定義に記述した通り、id、name、pageCountの3つを引数に取り戻り値はBook型のリゾルバであるregisterBookを定義します(コメントにもあるように中身はダミー実装です)
※リゾルバについては「GraphQLのリゾルバ(Resolver)とは」を参照ください。
@Component
public class BookResolver implements GraphQLQueryResolver, GraphQLMutationResolver {
public Book bookById(String bookId) {
// 実際は何らかのデータストアからデータを読み込み返却するケースがほとんどだが、ここではダミー値を返却
Book book = new Book();
book.setId(bookId);
book.setName("bookName");
book.setPageCount(900);
Author author = new Author();
author.setId("0001");
author.setFirstName("fName");
author.setLastName("lName");
book.setAuthor(author);
return book;
}
public Book registerBook(String id, String name, int pageCount) {
// 実際はここでデータ登録処理を行う
// GraphQLのスキーマ定義に則りBookを返却。一般的には登録後のデータを返却する。
Book book = new Book();
book.setId(id);
book.setName(name);
book.setPageCount(pageCount);
return book;
}
}
Mutationの実行
実際にMutationを投げてみます。全ての引数を設定して以下のように投げることができます。スキーマ定義上Book型が返ってくるため、ここではBook型の中のidとnameをレスポンスとしてもらうようなクエリにしています。
mutation {
registerBook(id: "1", name:"bookName", pageCount:100) {
id
name
}
}
レスポンスは以下のようになります。
{
"data": {
"registerBook": {
"id": "1",
"name": "bookName"
}
}
}
registerBookのname引数は必須なため、以下のようなクエリは構文エラーとなります。
mutation {
registerBook(id:"1", pageCount:100) {
id
name
}
}
逆に、name以外の引数は非必須なため、以下のようなクエリは実行可能です(必須な引数のみの指定)。
mutation {
registerBook(name:"bookName") {
id
name
}
}
1回のMutationで複数のデータ登録
複数のデータを登録するためにmutationにもう1つフィールドを追加します。ここではregisterAuthorを追加します。
type Mutation {
registerBook (
id: ID
name: String!
pageCount: Int
): Book
registerAuthor (
id: ID
firstName: String
lastName: String
): Author
}
サーバーサイドも以下のようにregisterAuthorを追加します。
@Component
public class BookResolver implements GraphQLQueryResolver, GraphQLMutationResolver {
public Book bookById(String bookId) {
// 実際は何らかのデータストアからデータを読み込み返却するケースがほとんどだが、ここではダミー値を返却
Book book = new Book();
book.setId(bookId);
book.setName("bookName");
book.setPageCount(900);
Author author = new Author();
author.setId("0001");
author.setFirstName("fName");
author.setLastName("lName");
book.setAuthor(author);
return book;
}
public Book registerBook(String id, String name, int pageCount) {
// 実際はここでデータ登録処理を行う
// GraphQLのスキーマ定義に則りBookを返却。一般的には登録後のデータを返却する。
Book book = new Book();
book.setId(id);
book.setName(name);
book.setPageCount(pageCount);
return book;
}
public Author registerAuthor(String id, String firstName, String lastName) {
// 実際はここでデータ登録処理を行う
// GraphQLのスキーマ定義に則りAuthorを返却。一般的には登録後のデータを返却する。
Author author = new Author();
author.setId(id);
author.setFirstName(firstName);
author.setLastName(lastName);
return author;
}
}
クエリは以下の通りです。
mutation {
registerBook(id:"1", name:"bookName", pageCount:100) {
id
name
pageCount
}
registerAuthor(id:"1", firstName:"fName", lastName: "lName") {
id
firstName
lastName
}
}
クエリ変数を使ってMutationを実行
「クエリ変数」というものを使ってMutationで登録する値を動的に変えることも可能です。クエリは以下のようになります。
mutation createBook($id:ID $name:String! $pageCount:Int) {
registerBook(id:$id, name:$name, pageCount: $pageCount) {
id
name
pageCount
}
registerAuthor(id:$id, firstName:"fName", lastName: "lName") {
id
firstName
lastName
}
}
クエリ変数を受け取るために構文上mutationの後に任意のmutation名が必要です(上記ではcreateBookとしています)。クエリ変数は頭に「$」を付けて任意の変数名となります。
GraphiQL、GraphQL Playgroundにはクエリ変数ウィンドウがあるので、そのウィンドウにて変数にセットする値をJSON形式で設定して実行します。JSONのキー名がクエリ変数名になります。
以上です。