はじめに
以下のような方達を対象に記事書いてます。
・GraphQLを初めて触る方
・とりあえずGraphQLで作成されたAPIを動かして動作させてみたい方
環境
仕事でGraphQLを検討することになったので、サンプルを作成しつつ、気になったところを検証してみようと思います。
・SpringBoot:3.3.2
・Java:17
・GraphQL:22.1
ソースコード
GraphQLの検証のためのサンプルなので、動作するためだけに書いてあるところが多いので、悪しからず
GraphQLとは
めっちゃざっくりいうと、
APIを開発するためのクエリ言語であり、REST APIより、データ取得効率を上げたり、柔軟性が上がることでクライアント側とコミュニケーションコストも減るなどを特徴に持ったFacebookによって開発されたクエリ言語とサーバーサイドのランタイム。
スキーマという構造を定義してQueryでデータを取得できたり、Mutationでデータの登録・更新・削除の操作ができる。
詳しく知りたい方は他の方の記事でGraphQLについてや仕組みについて解説されているので、そちらを読むと解像度上がると思います。
最低限のリクエストで必要なデータだけ返せるが、複雑になりがちってとこがみそっぽい。
基礎知識
まず最低限の基礎を紹介して、今回採用を検討するにあたって気になったところを紹介します。
スキーマ
APIのリクエストやレスポンスの構造を定義したり、定義したデータにアクセスするためのQueryやMutation、subscriptionを定義できる。
役割としては、
・データの構造の定義
・操作の定義
・バリデーション
type Book {
id: ID!
title: String!
author: Author!
}
type Author {
id: ID!
firstName: String!
lastName: String!
}
■Bookは以下の構造になってます。
・id: ID型を扱い必須項目
・title: String型を扱い必須項目
・author: Author型を扱い必須項目
■Authorは以下の構造になってます。
・id: ID型を扱い必須項目
・firstName: String型を扱い必須項目
・lastName: String型を扱い必須項目
ID
型はIntもしくは、String型を定義する。
!
は必須であることを定義する。
このように、GraphQLが定義しているデフォルトの型とカスタムの型を定義して、データ構造を定義できる。
Query
スキーマの中で定義できる操作の一つであり、データ取得操作を定義する。
type Query {
searchBookById(id: ID!): Book
}
type Book {
id: ID!
title: String!
author: Author!
}
type Author {
id: ID!
firstName: String!
lastName: String!
}
上記で定義している操作は、ID
型のidを指定し、Book
型でデータを返却すること(データが空であることを許容)を定義している。
ちなみに、リスト型を扱うには以下のようにQueryを修正すればOK。
type Query {
searchBooksByIds(ids: [ID!]!): [Book]
}
[]
で囲むとリスト型であることを定義する。
上記なら、リクエストは非NullのIDのリストでリストも非Nullであり、返却されるデータはBookのリストでNull許容であることを定義している。
Mutation
スキーマの中で定義できる操作の一つであり、データ登録・更新・削除操作を定義する。
type Mutation {
registerBook(title: String!, firstName String!, lastName String!): Book!
}
type Book {
id: ID!
title: String!
author: Author
}
type Author {
id: ID!
firstName: String!
lastName: String!
}
Mutationを定義するときは、type Mutation
ブロックで定義すればOK。
Subscription
Subscriptionはリアルタイム通信をするための定義で、サーバ側で特定のイベントが発生したり、データの変更を検知して、通知を送れる。
GraphQLサーバーでWebSocket通信をサポートする必要がある。
type Subscription {
newMessage: Message
}
type Message {
id: ID!
content: String!
sender: String!
}
Subscription
ブロックで定義できる。
次回
だらだらと書いてたら、長くなったので、記事分けますmm
参考文献