.github/workflows | ||
pages | ||
README.md |
marp | paginate |
---|---|
true | true |
GraphQL概論
WebDINO Japan エンジニア 渡邉浩平
GraphQLとは
サーバーへの問い合わせ (Query)
{
pokemon(name: "Pikachu") {
classification
}
}
サーバーからの応答 (Response, JSON形式)
{
"data": {
"pokemon": {
"classification": "Mouse Pokémon"
}
}
}
https://graphql-pokemon2.vercel.app
GraphQLとはAPIのクエリ言語
GraphQLとは
- APIのクエリ言語
- クエリ言語の型を宣言するGraphQLスキーマ言語
- Webクライアントとサーバーのためのアプリケーション層の仕様
:::info GraphQL以外の身近な言語の例:
- クエリ言語: SQL
- スキーマ言語: JSON Schema, XSD :::
歴史
- 2012年 Facebookによる開発
- 2015年 オープンソース化
- 2019年 GraphQL Foundationに移管
オープンソースな仕様になっており、自由に貢献可能
主な仕様
- サーバー: 使用可能なデータの構造とその操作を宣言するための言語 (スキーマ言語)
- クライアント: サーバーにデータを要求するための言語 (クエリ言語)
- サーバー: クエリの実行方法 (Resolvers)
- クライアント: 受け取るデータ形式 (JSON)
何でないか
- データベースではない
- JavaScriptではない
なぜGraphQLを使うのか
- 単一リクエスト
- 型システム
- 便利な開発ツール
1. 単一リクエスト
効率的なデータ読み込み
オーバーフェッチを最小限に抑え、サーバーへのラウンドトリップを少なくする FacebookがGraphQLを開発した理由は、モバイルネイティブアプリへの移行のため スマホの普及に伴う低速、省電力なデバイスの利用の増加が背景
REST
https://www.howtographql.com/basics/1-graphql-is-the-better-rest/
GraphQL
https://www.howtographql.com/basics/1-graphql-is-the-better-rest/
REST
GET /users/<id>
GET /users/<id>/posts
GET /users/<id>/followers
GraphQL
GET /?query={user(id:<id>){name,posts{title},followers(last:<count>){name}}}
2. 型システム
さまざまなフロントエンド環境のサポート
単一APIの構築と正確なデータ構造の維持 クライアントアプリケーションを実行するフロントエンドフレームワークとプラットフォームの多様化が背景
"""ポケモンを表します"""
type Pokemon {
"""このオブジェクトのID"""
id: ID!
"""このポケモンの全国図鑑No."""
number: String
"""このポケモンの名前"""
name: String
"""このポケモンの重さの最大と最小"""
weight: PokemonDimension
"""このポケモンの高さの最大と最小"""
height: PokemonDimension
"""このポケモンの分類"""
classification: String
# ...
}
特定のプログラミング言語に依存しないGraphQLスキーマ言語
"""ポケモンを表します"""
type Pokemon {
}
"""ポケモンの寸法を表します"""
type PokemonDimension {
}
オブジェクトの種類
"""ポケモンを表します"""
type Pokemon {
"""このオブジェクトのID"""
id: ID!
"""このポケモンの名前"""
name: String
"""このポケモンの分類"""
classification: String
"""このポケモンの高さの最大と最小"""
height: PokemonDimension
}
オブジェクトに含まれるフィールド
// JavaScript
const pokemonQuery = `{
pokemon(name: "Pikachu") {
classification
}
}`;
fetch(`http://example/?${new URLSearchParams({ query: pokemonQuery })}`)
.then(r => r.json())
.then(({ data }) => console.log(data?.pokemon?.classification));
// => "Mouse Pokémon"
// Kotlin
val response = apolloClient.query(pokemonQuery).await()
Log.d(response?.data?.pokemon?.classification)
// Swift
apollo.fetch(query: pokemonQuery) { result in
guard let data = try? result.get().data else { return }
print(data.pokemon?.classification)
}
3. 便利な開発ツール
短期間での開発
クライアントアプリケーションの設計変更に対応するためのツールが提供されている 継続的デプロイ (CD) が背景
IDE
GraphiQL, GraphQL Playground, etc.
コードの生成
$ graphql-codegen
使う
import { usePokemonQuery } from "./generated";
export default () => {
const { data } = usePokemonQuery();
return data?.pokemon?.classification;
};
GraphQL Code Generator React, Vue, Kotlin, etc.
まとめ
- GraphQLとはデータを問い合わせるクエリ言語仕様と周辺技術
- 単一リクエスト/型システム/便利な開発ツール
後付
より理解を深めるための知識
- 山本陽平「Webを支える技術」 - HTTPの基礎知識、REST
- GraphQL | A query language for your API
- How to GraphQL - The Fullstack Tutorial for GraphQL
何を話していないか
JSON Serialization
GraphQL Value | JSON Value |
---|---|
Map | Object |
List | Array |
Null | null |
String | String |
Boolean | true or false |
Int | Number |
Float | Number |
Enum Value | String |
https://spec.graphql.org/June2018/#sec-JSON-Serialization
セキュリティ
セキュリティの懸念事項は一般的なWebサービスと同様に存在
認証・認可
GraphQL仕様に含まないので一般的なWebの認証・認可の設計と同様に行う
キャッシュ
HTTP GETメソッドによる一般的なHTTP キャッシュに加え、GraphQLではグローバルなオブジェクトの識別子の宣言によるキャッシュが存在
(参考程度) 導入するか迷ったら…
digraph {
apps[shape=diamond,label="モバイルアプリ?"]
apps->GraphQL[label=Yes]
apps->REST[label=No]
{rank=same;apps;GraphQL}
}