0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GraphQL×Java入門 Mutation編

Posted at

はじめに

前回は、JavaでのQueryの実装例を紹介したので、今回はMutationを紹介します。
ただ、JavaでGraphQLの実装してもらうときのポイントとなるところを紹介するのがメインなので、ソースコードを作り込んでいるわけではないので、実務でそのまま使用するのは避けてくださいmm
(時短で結構適当にロジックや例外処理書いてあります)

環境

・SpringBoot:3.3.2
・Java:17
・GraphQL:22.1

ソースコード

GraphQL Sample

実装

1データ登録

スキーマ

type Mutation {
    registerBook(title: String!, author: AuthorInput!): Book!
}

type Book {
    id: ID!
    title: String!
    author: Author
}

input AuthorInput {
    id: ID!
    firstName: String!
    lastName: String!
}

コントローラ

@Controller
public class BookController {


    private final BookService bookService;

    public BookController(BookService bookService) {
        this.bookService = bookService;
    }

    @MutationMapping
    public BookResponse registerBook(@Argument("title") String title, @Argument("author") Author author) {

        Book book = bookService.registerBook(title, author);

        return new BookResponse(book.id().getId().toString(), book.title(), book.author());

    }

}

ユースケース

@Service
public class BookService {

   private final BookRepository bookRepository;

   private final AuthorRepository authorRepository;

   public BookService(BookRepository bookRepository, AuthorRepository authorRepository) {
       this.bookRepository = bookRepository;
       this.authorRepository = authorRepository;
   }

   public Book registerBook(String title, Author author) {
       UUID uuid = UUID.randomUUID();
       Book book = new Book(new BookId(uuid.toString()), title, author);

       if (!authorRepository.existById(author.id())) {
           authorRepository.register(author);
       }

       bookRepository.registerBook(book);

       return book;
   }

}

リポジトリ

public interface BookRepository {

   void registerBook(Book book);

}

@Repository
public class BookRepositoryImpl implements BookRepository {
   @Autowired
   DSLContext dslContext;

   @Override
   public void registerBook(Book book) {
       dslContext.insertInto(BOOK)
               .set(BOOK.ID, book.id().getId().toString())
               .set(BOOK.TITLE, book.title())
               .set(BOOK.AUTHORID, book.author().id())
               .execute();
   }

}

クエリ

mutation {
 registerBook(title: "mutationTest", 
 author: {
     id: "author-1",
     firstName: "first-test-name"
     lastName: "last-test-name" 
 }) {
   id 
   title
   author {
     id
     firstName
     lastName
   }
 }
}

実行結果

{
   "data": {
       "registerBookV2": {
           "id": "bf0892e1-5d63-4b42-aae5-50001130af4d",
           "title": "mutationTest",
           "author": {
               "id": "author-1",
               "firstName": "first-test-name",
               "lastName": "last-test-name"
           }
       }
   }
}

・コントローラクラス
Query書いているときは@QueryMappingのアノテーションを付与していたが、Mutationのときは@MutationMappingを付与すればOK

・スキーマ

type mutationでコマンド定義

リクエストでオブジェクト指定したい場合は、inputでデータ構造を定義

その他はQuery定義するときと変わらない。

複数データ登録

スキーマ

type Mutation {
  registerBookV2(bookList: [BookInput]!): Int!
}

input BookInput {
  title: String!
  author: AuthorInput!
}

input AuthorInput {
  id: ID!
  firstName: String!
  lastName: String!
}

クエリ

mutation {
registerBookV2(bookList: [
  {
    title: "title1"
    author: {
      id: "author-1",
      firstName: "first-author1"
      lastName: "last-author1"
    }
  },
  {
      title: "title2"
      author: {
        id: "author-2",
        firstName: "first-author2"
        lastName: "last-author2"
      }
  }
])

}

結果

{
  "data": {
      "registerBookV2": 2
  }
}

リストで受け取るコントローラ用意して、スキーマでは、リストを指定するコマンドを定義すれば、複数データ登録もできます。

ちなみに以下のように複数回コマンド実行して、複数データ登録することもできます。

クエリ


mutation {
book1: registerBookV2(bookList: {
    title: "title1"
    author: {
      id: "author-1",
      firstName: "first-author1"
      lastName: "last-author2"
    }
})

book2: registerBookV2(bookList: {
    title: "title1"
    author: {
      id: "author-1",
      firstName: "first-author1"
      lastName: "last-author2"
    }
})
}

結果

{
  "data": {
      "book1": 1,
      "book2": 1
  }
}

別々のコマンド実行を1度のリクエストで完結したいときは、使用するのだろうが、1度のリクエストで同じコマンドを複数回実行することは、実際の業務ではほとんどないと思います。

さいごに

今回はJavaでのMutation実装例を紹介させてもらいました。
次はエラーハンドリング周りの紹介をしますー

参考文献

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?