【めっちゃ便利!】GraphQLについてざっくり理解する
はじめに
今回は、会社で学んだ知識のoutputとして、GraphQLについての記事を執筆しようと思います。
GraphQLってなんなの?という人に向けての記事になるので、見ていただけると幸いです。
想定読者
- GraphQLって聞いたことはあるけど、なんだか分からない人
- APIを少しは触ったことがあるひと
- (サンプルコードを実行したい人は)dockerの基礎が分かる人(go+ gqlgenを使用します。)
では、早速本題です。
で、GraphQLってなんなの?
GraphQLはすごく簡単に言うと、
FaceBookが作った新しいAPIの規格!!
記事を読んでくださっている皆さんはよく見るAPIは
RESTfulAPIなのではないかと思います。
GraphQLは新しいAPI規格と言うだけあって、
RESTfulAPIとはかなり違った書き方、考え方になっています。
ここから、
GraphQLについて、RESTfulAPIと比較しながら紹介できればと思います。
RESTful APIと何が違うの?
こちらは、RESTfulAPIとGraphQLの違いを表した図になります。
細かく言うと違いはたくさんあるのですが、、、
大きく分けて、違いは2つです。
もう少し詳しく見ていきましょう。
1. エンドポイントの数
上の比較図を見てもらえればわかると思うのですが、エンドポイントの数が違います。
RESTfulAPIだと・・・・
students
,courses
, instructors
のようにリソース毎にエンドポイントが設定されているのがわかります。
一方で、
GraphQLの場合・・・
リソースの数に関わらず、エンドポイントが一つになっていることがわかると思います。
何で一つでいいの? って思う方もいらっしゃると思うのですが、
これは、クエリパラメータ
によって取得したい値やリソースを選択することができるからです。
比較図はこんな感じ
Restful API | GraphQL | |
---|---|---|
エンドポイント | リソース毎に作成する必要がある。 | 基本的に一つでよい。 |
2.データの追加、更新、削除などの考え方
データ追加、更新、削除の考え方が少し違います、
APIをコールするときのことを考えてください。
RESTfulAPIだと・・・
HTTPメソッドに応じてデータを追加したり、更新したりすると思います。
例えば、
students(生徒)のデータを操作したいときのことを考えます。
- データを追加する場合は、HTTPメソッドのPOST
-
データを削除する場合は、HTTPメソッドのDELETE
ほかにも、GET, PUT(PATCH) などを使用すると思います。
一方で、
GraphQLの場合・・・
二種類の操作(GraphQL QueryとGraphQL Mutation)を使うだけで良くなります。
subscripitonという操作も存在するのですが、今回は割愛します。
例えば
RESTfulAPIと同様に、students(生徒)のデータを操作したいときのことを考えます。
- データを取得 したい場合は、GraphQL Queryを使用する
- データを追加、更新、削除したい場合は、GraphQL Mutaionを使用する
このように2つだけ、取得、追加、更新、削除の処理を実行できます。
図にまとめるとこんな感じ
Restful API | GraphQL | |
---|---|---|
データの取得 | GET | Query |
データの追加 | POST | Mutation |
データの更新 | UPDATE | Mutation |
データの削除 | DELETE | Mutation |
じゃ、どう書けばいいんすか?
GraphQLでは2つ書くべきものがあります。
- GraphQLスキーマ(どういうデータを返すかを記載した仕様書のようなもの)
- GraphQLクエリ(こういうデータがほしいです、というのを記載したもの→APIのリクエストで使います)
graphQLではこのような記述をします。
今回はstudentsの情報を取得、更新するためのAPIを考えます。
まずはスキーマ
型やGraphQLの2つの操作を記載します。
type Query { #Queryは予約語→データ取得を行いたい処理を記載
getStudents: [students] # Query名(引数):型
}
input Student {
name: String!
age: Int!
grade: Int!
}
type Mutation { #Mutationも予約後→データ更新系を行いたい処理を記載
createStudent(input: Student): students # Mutation名(引数:型):型
}
type students { # ←このように独自に型、objectを作る事も可能
name: String!
age: Int!
grade: Int!
}
次にクエリ
実際にスキーマが完成したので、APIを実行してみましょう。
このような処理を記述します。
# <query or mutation> <任意の名前>
query getStudents {
name # 取得したい値のみを選択
age
}
レスポンスとしては以下のとおり
{
"data": {
"getStudents": [
{
"name": "一郎",
"age": 20
},
{
"name": "二郎",
"age": 18
},
]
}
}
上の見ていただいたら、わかると思うのですが、APIを叩くときもjson構造のような指定の仕方をします。
GraphQLはなにがいいの?
上記を踏まえてまとめると以下のとおりです。
- クライアントが好きな値のみを取得することができる。
- RESTful APIはOverfetchingになりがち
- studentの名前情報だけほしかったとしても,他の情報も取得してしまう
- RESTful APIはOverfetchingになりがち
- 直感的に記述できる
- 上記の実行例を見てもらえばわかるようにほしい値をjson構造のような形で記載すればよいので、直感的
- エンドポイントが増えすぎるのを防ぐことができる
じゃ、どうやってうごかすの?
実際に例としてgolangのgqlgenライブラリを利用して実装してみます。
必要ファイル
docker-compose.yml (中身はこちらをクリック
version: "2"
services:
sample:
build: .
tty: true
volumes:
- ./:/mnt
ports:
- 8081:8080
Dockerfile (中身はここをクリック
FROM golang:alpine
WORKDIR /mnt
RUN go get -d -v golang.org/x/net/html
COPY . .
実行手順
コンテナ環境にログイン
# コンテナ環境を起動
$ docker-compose up -d
# コンテナ環境にログイン
$ docker-compose exec sample sh
GraphQLのスキーマの設計
type Query { #Queryは予約語→データ取得を行いたい処理を記載
getStudents: [students] # Query名(引数):型
}
input Student {
name: String!
age: Int!
grade: Int!
}
type Mutation { #Mutationも予約後→データ更新系を行いたい処理を記載
createStudent(input: Student): students # Mutation名(引数:型):型
}
type students { # ←このように独自に型、objectを作る事も可能
name: String!
age: Int!
grade: Int!
}
雛形ファイル作成
go run github.com/99designs/gqlgen init
上記コマンドを実行すると、自動的にひな形ファイルが生成されます、
処理追加
以下のファイルに処理を追加します
func (r *mutationResolver) CreateStudent(ctx context.Context, input *model.Student) (*model.Students, error) {
student := &model.Students{
Name: input.Name,
Age: input.Age,
Grade: input.Grade,
}
r.students = append(r.students, student)
return student, nil
}
func (r *queryResolver) GetStudents(ctx context.Context) ([]*model.Students, error) {
return r.students, nil
}
graphqlサーバー起動&アクセス
#サーバー起動
$ go run server.go
2021/04/18 06:10:31 connect to http://localhost:8080/ for GraphQL playground
http://localhost:8081 にアクセスすると以下のような画面が表示される
この画面でgraphqlを試すことが可能です。
まとめ
- GraphQLとは
- 新しいAPI規格
- データ取得にはQuery、データ更新系にはMutationを使う
- GraphQLの特徴
- エンドポイントが一つあればよい
- 直感的に記述できる
最後に
graphqlについて簡単に解説してみました。
何かわからないこと、間違っていることなどがあればコメントお願いします。
参考
Discussion