GraphQLとは
GraphQL の公式サイトを直訳すると上記のような表現になりますが、以下のように捉えてください
・GraphQL は、クライアント-サーバー間のデータ問い合わせに特化したクエリ言語(問合せ言語)である。
・GraphQL には、データ問い合わせを行うクエリ言語とは別に、データの構造を定義するスキーマ言語をもち、このスキーマ言語によってデータ構造の型定義を行うことができ、定義された型を用いることにより、型安全なデータ通信が可能になる。
また、GraphQLはJavascriptを筆頭にRuby、GoやPythonといった様々な言語と組み合わせることができます。
さっそくGraphQLのスキーマとクエリのシンプルな例として下記の公式サイトにあったスキーマを使ってみていきます。
type Query {
me: User
}
type User {
id: ID
name: String
email: String
}
Query型はただひとつのUser型をかえすmeフィールドを持ち、User型はID型のid、String型のnameとString型のemailのフィールドをかえします。
例えば次のようなnameだけを返すようなクエリ(Query)を発行すると、
{
me{
name
}
}
これに対応するレスポンスは、例えば次のようなJSONデータになります。
{
"me": {
"name": "Kimmich"
}
}
REST APIとの違い
上の例でわかった人もいると思います。従来の REST APIではユーザーのnameだけを返すように指定することはできず、ユーザーデータ(上の例だとid、name、email)をすべて返します。一方でGraphQLではクライアント側でレスポンスのデータ型を指定することができます。 また、REST APIは/user/1のように固有のエンドポイントを指定する必要がありアプリケーションが大規模になるとごちゃごちゃしてしまいます。GraphQLであればクライアント側で呼び出すエンドポイントは例えば”http://localhost:4000/graphql”のようにひとつです。
しかしながら、GraphQLにもデメリットが存在します。まず動画や画像などの大容量のバイナリデータを扱うことが苦手です。なので画像データ等を保存したい場合などはRESTを使用するべきである。またパフォーマンスの記録や分析などを行うときはエンドポイントごとに 情報を収集するのでどうしてもパフォーマンスの分析が難しくなります。さらに学習コストも存在します。GraphQLは従来のREST APIと大きく違うので概念などの習得に時間を要することが考えられます。
まとめるとGraphQLには上記以外のメリットもデメリットも存在し、またそれはREST APIも同様であり、REST APIが出来なかったことがGraphQLは出来ることもあります。 それぞれの特徴を理解し使いわけることが大切で、筆者としては選択肢のひとつという意味で学習してほしいと思ってこのサイトを作成しています。
GraphQL のQueryとMutation
Queryについて
GraphQLのQueryはいわゆるCRUDでいうところのGETにあたり、大まかにいうとデータ取得時に使われます。
先ほどと同じような例で確かめましょう。
type Query {
users: [User!]!
user(id: Int!): User!
}
type User {
id: ID!
name: String!
friends: [String!]!
}
usersフィールドは複数のユーザーを返します。そしてuserフィールドはidを指定し、そのidを持つひとりのユーザーを返します。(ちなみに ! は null を許容しないフィールドであることを示しています。)
usersは以下のように定義します。
const users = [
{
id: 1,
name: "Messi",
friends: [
"Ronaldo",
"Mount",
"Kean"
]
},
{
id: 2,
name: "Mane",
friends: [
"Alison",
"Morta",
]
},
{
id: 3,
name: "Kimmich",
friends: [
"Thiago",
"Muller"
]
}
]
usersでidとnameを返すように指定する。
//query名は省略することができる。
//ここではgetUsersと名付ける。
query getUsers {
users{
id
name
}
}
{
"data": {
"users": [
{
"id": "1",
"name": "Messi"
},
{
"id": "2",
"name": "Mane"
},
{
"id": "3",
"name": "Kimmich"
}
]
}
}
次はidを指定してname,friendsを返すように定義します。
{
user(id: 1){
name
friends
}
}
{
"data": {
"user": {
"name": "Messi",
"friends": [
"Ronaldo",
"Mount",
"Kean"
]
}
}
}
Mutationについて
MutationはCRUDでいうところのPOST、UPDATE、DELETEに当てはまる。 データの作成、更新や削除するときに使う。
例としてユーザーを作成してみます。ちなみにQueryのqueryのときと違い、mutationは省略できません。
mutation {
createUser(id: 4, name: "Gnabry", friends: []){
name
}
}
上の例では新しくユーザーを作成し、そのユーザーのnameフィールドを返すように指定しています。queryのときと同じようにかえってきます。
{
"data": {
"createUser": {
"name": "Gnabry"
}
}
}
QueriesとMutations以外にもSubscriptionsというものがあるがあまり使わないのでここでは説明は省略します。別ページで紹介しているので是非チェックしてください。リンクはこちら
GraphQLのType
Type(型)について
GraphQLにおいて冒頭やQueryで扱ったようなスキーマ(Schema)を定義するときに重要な要素であり、GraphQLは独自の型システムのもちますが、他の言語と同様にデータを識別するために用いられます。そしてGraphQLには大きく分けてスカラー型とオブジェクト型が存在します。
スカラー型
- String(文字列型)
- Int(整数型)
- Float(浮動小数点型)
- Boolean(論理型)
- ID(ID型)
上の5つのスカラー型が存在します。
オブジェクト型
1つ以上のスキーマで定義されているフィールドの集合をオブジェクト型といいます。Queryの説明のときに使ったuser(id: Int!): User!のUserが例のひとつです。[User]のように[ ]でかこむことでリストを定義しています。(複数という意味)また前述しましたが!をつけることでnullにならないフィールドという意味を持ちます。
Enum型について
enum Position {
FW
MF
DF
GK
}
上のような形で定義され、これはEpisodeというスキーマを使うときに必ずどれかひとつでも定義された値をかえすということを表しています。
インターフェイス(interface)について
他の言語の型システムのようにGraphQLもインターフェイスと呼ばれる機能を持ちます。
interface User {
id: ID!
name: String!
email: String!
}
type worker implements User {
id: ID!
name: String!
email: String!
password: String!
}
type adminUser implements User {
id: ID!
name: String!
email: String!
password: String!
}
type CEO implements User {
id: ID!
name: String!
email: String!
specialPassword: String!
}
上の例からわかるようにUserを実装しているスキーマはUserがもつフィールドを全て持つということを示しています。また、以下のように数種類の要素がある場合を表すのに便利です。
Query listingUser {
findAllUser: [User]
}
interface User {
id: ID!
name: String!
email: String!
}
type worker implements User {
id: ID!
name: String!
email: String!
password: String!
}
type admin implements User {
id: ID!
name: String!
email: String!
adminPassword: String!
}
type CEO implements User {
id: ID!
name: String!
email: String!
specialPassword: String!
}
findAllUserはUserのリストをかえします。Userインターフェイスフィールドはworker,admin,CEOのすべてのタイプに共通しているため、これら3タイプ全てをUserインターフェイスの任意のフィールドを返してくれます。
ユニオン(Union)型について
ユニオン型はインターフェイスと似ています。共通のフィールドをかえすのではなく与えられた複数の型のうち1つを返す型です。
Query listingUser {
findAllUser: [User]
searchUser(id: Int): SearchResult
}
union SearchResult = worker | admin | CEO
上のような表現で与えられた3つのうちのどれかをかえすという型です。
まとめ
このページでは大まかにGraphQLのコアコンセプトについてまとめました。このサイトではいくつかのチュートリアルを用意してあるので実際に手を動かしてチャレンジしてみてください。
Menu