intro-to-graphql/README.md
2021-07-20 15:00:57 +09:00

10 KiB

marp paginate
true true

GraphQL 概論

WebDINO Japan エンジニア 渡邉浩平 w:200


GraphQL とは

https://graphql.org


GraphQL とは API のクエリ言語

サーバーへの問い合わせ (GraphQL Query)

query {
  pokemon(name: "Pikachu") {
    classification
  }
}

サーバーからの応答 (JSON)

{
  "data": {
    "pokemon": {
      "classification": "Mouse Pokémon"
    }
  }
}

https://graphql-pokemon2.vercel.app


歴史

  • 2012 年 Facebook による開発
  • 2015 年 オープンソース化
  • 2019 年 GraphQL Foundationに移管

オープンソースな仕様になっており、自由に貢献可能


主な仕様

GraphQL 以外の身近な言語の例:


何でないか

  • データベースではない
  • JavaScript ではない

なぜ GraphQL を使うのか

  1. 単一リクエスト
  2. 型システム
  3. 開発ツール

1. 単一リクエスト

効率的なデータ読み込み

Facebook が GraphQL を開発した理由は、モバイルネイティブアプリへの移行のため スマホの普及に伴う低速、省電力なデバイスの利用の増加が背景

REST は複数のエンドポイントへの問い合わせを行うという典型的な課題がある クライアントのデータ取得の効率やデータの表現の都合で似たような振る舞いの API を作りがち

GraphQL は単一のリクエストで指定したデータを取得可能 オーバーフェッチを最小限に抑え、サーバーへのラウンドトリップを少なくする


REST

h:600 REST https://hasura.io/learn/graphql/intro-graphql/graphql-vs-rest/


GraphQL

h:600 GraphQL https://hasura.io/learn/graphql/intro-graphql/graphql-vs-rest/


2. 型システム

さまざまなフロントエンド環境のサポート

単一 API の構築と正確なデータ構造の維持 クライアントアプリケーションを実行するフロントエンドフレームワークとプラットフォームの多様化が背景


GraphQL Schema

"""ポケモンを表します"""
type Pokemon {
  """このオブジェクトのID"""
  id: ID!

  """このポケモンの名前"""
  name: String

  # ...
}

"""ポケモンの寸法を表します"""
type PokemonDimension {
  # ...
}

"""ポケモンを表します"""
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

h:600 GraphiQL


GraphQL Code Generator

コードの生成

$ graphql-codegen

使う

import { usePokemonQuery } from "./generated";

export default () => {
  const { data } = usePokemonQuery();
  return data?.pokemon?.classification;
};

React, Vue, Kotlin, etc.

https://www.graphql-code-generator.com


Hasura

GraphQL サーバー 接続したデータベースを自動的に GraphQL API として提供

https://hasura.io


まとめ

  • GraphQL とはデータを問い合わせるクエリ言語仕様と周辺技術
  • 単一リクエスト/型システム/開発ツール

GraphQL をもっと知る

使うための知識を深める


GraphQL Operation

3 種類の操作

  • query - 読み取り
  • mutation - 書き込み
  • subscription - イベントストリーム

1 つのリクエストに複数の操作を含めることが可能


Query - データの取得


基本的な構文

query {
  pokemon(name: "Pikachu") {
    classification
  }
}

query … 操作 name … 引数 "Pikachu" … 値 pokemon, classification … フィールド


子孫関係

query {
  pokemon(name: "Pikachu") {
    classification
    height {
      minimum
      maximum
    }
  }
}

height フィールドの中の minimum, maximum フィールド


変数を使った query の再利用

query ($name: String!) {
  pokemon(name: $name) {
    classification
    height {
      minimum
      maximum
    }
  }
}

+

{
  "name": "Pikachu"
}

$name … 変数 String! … 型


操作を名付ける

query fetchPikachu {
  pokemon(name: "Pikachu") {
    classification
  }
}

fetchPikachu … 操作名


フィールドを名付ける

query {
  pikachu: pokemon(name: "Pikachu") {
    classification
  }
}

pikachu … エイリアス


フラグメント

fragment dimension on PokemonDimension {
  minimum
  maximum
}

query {
  pokemon(name: "Pikachu") {
    classification
    height {
      ...dimension
    }
    weight {
      ...dimension
    }
  }
}

dimension … フラグメント


ディレクティブ

query ($showClassification: Boolean!) {
  pokemon(name: "Pikachu") {
    classification @include(if: $showClassification)
  }
}

+

{
  "showClassification": true
}

@include … ディレクティブ


まとめ

  • 3 種類の操作
  • Query によるデータの取得

後付


より理解を深めるための知識


何を話していないか


セキュリティ

セキュリティの懸念事項は一般的な Web サービスと同様に存在


認証・認可

GraphQL 仕様に含まないので一般的な Web の認証・認可の設計と同様に行う


キャッシュ

HTTP GET メソッドによる一般的なHTTP キャッシュに加え、GraphQL ではグローバルなオブジェクトの識別子の宣言によるキャッシュが存在


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


フィードバック

このスライドを編集する / 問題を報告する