2021-05-27 19:54:00 +09:00
---
marp: true
paginate: true
---
# GraphQL概論
WebDINO Japan エンジニア
[渡邉浩平 ](https://github.com/kou029w )
![w:200 ](https://github.com/kou029w.png )
---
2021-05-27 21:20:20 +09:00
## GraphQLとは
https://graphql.org
---
### GraphQLとはAPIのクエリ言語
2021-05-27 19:54:00 +09:00
2021-05-28 01:37:08 +09:00
サーバーへの問い合わせ (GraphQL Query)
2021-05-27 19:54:00 +09:00
```graphql
2021-05-28 00:47:16 +09:00
query {
2021-05-27 19:54:00 +09:00
pokemon(name: "Pikachu") {
classification
}
}
```
2021-05-28 01:37:08 +09:00
サーバーからの応答 (JSON)
2021-05-27 19:54:00 +09:00
```json
{
"data": {
"pokemon": {
"classification": "Mouse Pokémon"
}
}
}
```
https://graphql-pokemon2.vercel.app
---
2021-05-29 07:33:09 +09:00
## 歴史
- 2012年 Facebookによる開発
- 2015年 オープンソース化
- 2019年 [GraphQL Foundation ](https://graphql.org/foundation/ )に移管
オープンソースな仕様になっており、自由に[貢献可能 ](https://github.com/graphql/graphql-spec/blob/main/CONTRIBUTING.md )
---
## 主な仕様
2021-05-27 19:54:00 +09:00
2021-05-28 01:41:45 +09:00
- [サーバーにデータを要求するための言語 (クエリ言語) ](https://graphql.org/learn/queries/ )
- [クライアントの受け取るデータ形式 (JSON) ](https://graphql.org/learn/serving-over-http/#response )
- [使用可能なデータの構造とその操作を宣言するための言語 (スキーマ言語) ](https://graphql.org/learn/introspection/ )
- [クエリの実行方法 ](https://graphql.org/learn/execution/ )
2021-05-27 19:54:00 +09:00
2021-05-27 21:20:20 +09:00
### GraphQL以外の身近な言語の例:
2021-05-27 19:54:00 +09:00
- クエリ言語: SQL
- スキーマ言語: [JSON Schema ](https://json-schema.org/ ), [XSD ](http://www.w3.org/TR/xmlschema11-1/ )
---
## 何でないか
- データベースではない
- JavaScriptではない
---
## なぜGraphQLを使うのか
1. 単一リクエスト
2. 型システム
2021-05-28 01:10:33 +09:00
3. 開発ツール
2021-05-27 19:54:00 +09:00
---
### 1. 単一リクエスト
効率的なデータ読み込み
FacebookがGraphQLを開発した理由は、[モバイルネイティブアプリへの移行のため ](https://reactjs.org/blog/2015/05/01/graphql-introduction.html )
スマホの普及に伴う低速、省電力なデバイスの利用の増加が背景
2021-05-28 17:35:45 +09:00
RESTは複数のエンドポイントへの問い合わせを行うという典型的な課題がある
クライアントのデータ取得の効率やデータの表現の都合で似たような振る舞いのAPIを作りがち
GraphQLは単一のリクエストで指定したデータを取得可能
オーバーフェッチを最小限に抑え、サーバーへのラウンドトリップを少なくする
2021-05-27 19:54:00 +09:00
---
2021-05-27 21:20:20 +09:00
#### REST
2021-05-27 19:54:00 +09:00
2021-05-27 23:18:38 +09:00
![h:600 REST ](https://graphql-engine-cdn.hasura.io/learn-hasura/assets/graphql-react/rest-api.png )
https://hasura.io/learn/graphql/intro-graphql/graphql-vs-rest/
2021-05-27 19:54:00 +09:00
---
2021-05-27 21:20:20 +09:00
#### GraphQL
2021-05-27 19:54:00 +09:00
2021-05-27 23:18:38 +09:00
![h:600 GraphQL ](https://graphql-engine-cdn.hasura.io/learn-hasura/assets/graphql-react/graphql-api.gif )
https://hasura.io/learn/graphql/intro-graphql/graphql-vs-rest/
2021-05-27 19:54:00 +09:00
---
### 2. 型システム
さまざまなフロントエンド環境のサポート
単一APIの構築と正確なデータ構造の維持
クライアントアプリケーションを実行するフロントエンドフレームワークとプラットフォームの多様化が背景
---
2021-05-28 10:07:48 +09:00
#### GraphQL Schema
2021-05-27 21:20:20 +09:00
2021-05-27 19:54:00 +09:00
```graphql=
"""ポケモンを表します"""
type Pokemon {
"""このオブジェクトのID"""
id: ID!
"""このポケモンの全国図鑑No."""
number: String
"""このポケモンの名前"""
name: String
"""このポケモンの重さの最大と最小"""
weight: PokemonDimension
"""このポケモンの高さの最大と最小"""
height: PokemonDimension
"""このポケモンの分類"""
classification: String
# ...
}
```
---
```graphql
"""ポケモンを表します"""
type Pokemon {
}
"""ポケモンの寸法を表します"""
type PokemonDimension {
}
```
オブジェクトの種類
---
```graphql
"""ポケモンを表します"""
type Pokemon {
"""このオブジェクトのID"""
id: ID!
"""このポケモンの名前"""
name: String
"""このポケモンの分類"""
classification: String
"""このポケモンの高さの最大と最小"""
height: PokemonDimension
}
```
オブジェクトに含まれるフィールド
---
2021-05-27 21:20:20 +09:00
#### 特定のプログラミング言語に依存しない
2021-05-27 19:54:00 +09:00
```javascript
// JavaScript
2021-05-27 21:20:20 +09:00
const pokemonQuery = `{ pokemon(name: "Pikachu") { classification } }` ;
2021-05-27 19:54:00 +09:00
fetch(`http://example/?${new URLSearchParams({ query: pokemonQuery })}` )
.then(r => r.json())
.then(({ data }) => console.log(data?.pokemon?.classification));
// => "Mouse Pokémon"
```
```kotlin
// Kotlin
val response = apolloClient.query(pokemonQuery).await()
Log.d(response?.data?.pokemon?.classification)
```
```swift
// Swift
apollo.fetch(query: pokemonQuery) { result in
guard let data = try? result.get().data else { return }
print(data.pokemon?.classification)
}
```
https://www.apollographql.com
---
2021-05-28 01:10:33 +09:00
### 3. 開発ツール
2021-05-27 19:54:00 +09:00
短期間での開発
クライアントアプリケーションの設計変更に対応するためのツールが提供されている
継続的デプロイ (CD) が背景
---
2021-05-27 21:20:20 +09:00
#### IDE - GraphiQL
2021-05-27 19:54:00 +09:00
2021-05-27 21:20:20 +09:00
![h:600 GraphiQL ](https://raw.githubusercontent.com/graphql/graphiql/main/packages/graphiql/resources/graphiql.jpg )
2021-05-27 19:54:00 +09:00
2021-05-27 21:20:20 +09:00
https://github.com/graphql/graphiql
2021-05-27 19:54:00 +09:00
---
2021-05-27 21:20:20 +09:00
#### GraphQL Code Generator
2021-05-27 19:54:00 +09:00
コードの生成
```console
$ graphql-codegen
```
使う
```typescript
import { usePokemonQuery } from "./generated";
export default () => {
const { data } = usePokemonQuery();
return data?.pokemon?.classification;
};
```
[React ](https://www.graphql-code-generator.com/docs/plugins/typescript-react-query ), [Vue ](https://www.graphql-code-generator.com/docs/plugins/typescript-vue-apollo ), [Kotlin ](https://www.graphql-code-generator.com/docs/plugins/kotlin ), etc.
2021-05-27 23:13:23 +09:00
https://www.graphql-code-generator.com
2021-05-27 19:54:00 +09:00
---
2021-05-27 23:11:31 +09:00
#### Hasura
GraphQLサーバー
接続したデータベースを自動的にGraphQL APIとして提供
https://hasura.io
---
2021-05-28 01:10:33 +09:00
## まとめ
2021-05-27 19:54:00 +09:00
- GraphQLとはデータを問い合わせるクエリ言語仕様と周辺技術
2021-05-28 01:10:33 +09:00
- 単一リクエスト/型システム/開発ツール
2021-05-27 19:54:00 +09:00
---
2021-05-28 00:47:16 +09:00
## GraphQLをもっと知る
2021-05-27 19:54:00 +09:00
2021-05-28 17:35:45 +09:00
使うための知識を深める
2021-05-27 19:54:00 +09:00
---
2021-05-28 01:10:33 +09:00
## GraphQL Operation
2021-05-27 19:54:00 +09:00
2021-05-28 00:47:16 +09:00
3種類の操作
- query - 読み取り
- mutation - 書き込み
- subscription - イベントストリーム
1つのリクエストに複数の操作を含めることが可能
2021-05-27 19:54:00 +09:00
---
2021-05-28 01:10:33 +09:00
## Query - データの取得
---
2021-05-28 00:47:16 +09:00
### 基本的な構文
2021-05-27 19:54:00 +09:00
2021-05-28 00:47:16 +09:00
```graphql
query {
pokemon(name: "Pikachu") {
classification
}
}
```
`query` … 操作
`name` … 引数
`"Pikachu"` … 値
`pokemon` , `classification` … フィールド
---
子孫関係
```graphql
query {
pokemon(name: "Pikachu") {
classification
height {
minimum
maximum
}
}
}
```
`height` フィールドの中の `minimum` , `maximum` フィールド
---
2021-05-28 01:10:33 +09:00
変数を使ったqueryの再利用
2021-05-28 00:47:16 +09:00
```graphql
query ($name: String!) {
pokemon(name: $name) {
classification
height {
minimum
maximum
}
}
}
```
\+
```json
{
"name": "Pikachu"
}
```
`$name` … 変数
`String!` … 型
---
操作を名付ける
```graphql
query fetchPikachu {
pokemon(name: "Pikachu") {
classification
}
}
```
`fetchPikachu` … 操作名
---
フィールドを名付ける
```graphql
query {
pikachu: pokemon(name: "Pikachu") {
classification
}
}
```
`pikachu` … エイリアス
---
フラグメント
```graphql
fragment dimension on PokemonDimension {
minimum
maximum
}
query {
pokemon(name: "Pikachu") {
classification
height {
...dimension
}
weight {
...dimension
}
}
}
```
`dimension` … フラグメント
---
ディレクティブ
```graphql
query ($showClassification: Boolean!) {
pokemon(name: "Pikachu") {
classification @include (if: $showClassification)
}
}
```
\+
```json
{
"showClassification": true
}
```
`@include` … ディレクティブ
2021-05-27 19:54:00 +09:00
---
2021-05-28 00:47:16 +09:00
## まとめ
2021-05-28 01:10:33 +09:00
- 3種類の操作
- Queryによるデータの取得
2021-05-28 00:47:16 +09:00
---
## 後付
---
### より理解を深めるための知識
- [山本陽平「Webを支える技術」 ](https://gihyo.jp/book/2010/978-4-7741-4204-3 ) - HTTPの基礎知識、REST
- [GraphQL \| A query language for your API ](https://graphql.org/ )
- [How to GraphQL \- The Fullstack Tutorial for GraphQL ](https://www.howtographql.com/ )
- [Fullstack GraphQL Tutorial Series \| Learn GraphQL Frontend and Backend ](https://hasura.io/learn/ )
---
### 何を話していないか
- [Mutation ](https://graphql.org/learn/queries/#mutations )
- [Introspection ](https://graphql.org/learn/introspection/ )
- [エラーレスポンス ](http://spec.graphql.org/June2018/#sec-Errors )
- [Validation ](https://graphql.org/learn/validation/ )
- [Execution ](https://graphql.org/learn/execution/ )
- [Subscription ](https://spec.graphql.org/June2018/#sec-Subscription )
---
2021-05-27 19:54:00 +09:00
### セキュリティ
セキュリティの懸念事項は一般的なWebサービスと同様に存在
- [OWASP Top Ten ](https://owasp.org/www-project-top-ten/ )
- [GraphQL \- OWASP Cheat Sheet Series ](https://cheatsheetseries.owasp.org/cheatsheets/GraphQL_Cheat_Sheet.html )
---
### 認証・認可
GraphQL仕様に含まないので一般的なWebの認証・認可の設計と同様に行う
- [OpenID ](https://openid.net/ )
- [OAuth ](https://oauth.net/ )
- [JWT ](https://jwt.io/ )
---
### キャッシュ
HTTP GETメソッドによる一般的な[HTTP キャッシュ ](https://developer.mozilla.org/ja/docs/Web/HTTP/Caching )に加え、GraphQLでは[グローバルなオブジェクトの識別子の宣言 ](https://graphql.org/learn/global-object-identification/ )による[キャッシュ ](https://graphql.org/learn/caching/ )が存在
2021-05-28 01:10:33 +09:00
---
### JSON Serialization
GraphQL Value |JSON Value
---|---
Map |Object
List |Array
Null |null
String/Enum Value |String
Boolean |true or false
Int/Float |Number
https://spec.graphql.org/June2018/#sec -JSON-Serialization