Help us understand the problem. What is going on with this article?

GraphQLでMutation

本記事では「Spring BootでGraphQLを実装する」で使ったサンプルアプリを例に記述します。

Mutationのスキーマ定義

まずMutationの命名はアプリケーションと紐づく動詞が望ましいです。今回は、id、name、pageCountの3つを引数に取り戻り値はBook型のスキーマを定義してみます。
※この後の説明の都合上、nameフィールドは必須、それ以外は非必須となる引数としています。
※「!」の詳細は「GraphQLのスキーマと型定義のエクスクラメーションマークの意味」を参照ください。

schema.graphqls
type Mutation {
    registerBook (
        id: ID
        name: String!
        pageCount: Int
    ): Book
}

サーバーサイド

サーバーサイドの実装は以下の通りです。GraphQLMutationResolverをimplementsする必要があります(Javaで実装しているためこのようにしています、他の言語では違った形になるかと思います)。また、スキーマ定義に記述した通り、id、name、pageCountの3つを引数に取り戻り値はBook型のリゾルバであるregisterBookを定義します(コメントにもあるように中身はダミー実装です)
※リゾルバについては「GraphQLのリゾルバ(Resolver)とは」を参照ください。

BookResolver.java
@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を追加します。

schema.graphqls
type Mutation {
    registerBook (
        id: ID
        name: String!
        pageCount: Int
    ): Book

    registerAuthor (
        id: ID
        firstName: String
        lastName: String
    ): Author
}

サーバーサイドも以下のようにregisterAuthorを追加します。

BookResolver.java
@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のキー名がクエリ変数名になります。
キャプチャ.PNG

以上です。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした