GraphQL 概論
Find a file
2021-05-28 01:22:28 +09:00
.github/workflows fix workflows 2021-05-28 01:22:28 +09:00
pages update 2021-05-27 20:07:44 +09:00
README.md fix 2021-05-28 01:10:33 +09:00

marp paginate
true true

GraphQL概論

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


GraphQLとは

https://graphql.org


GraphQLとはAPIのクエリ言語

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

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

サーバーからの応答 (Response, JSON形式)

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

https://graphql-pokemon2.vercel.app


GraphQLとは

  • APIのクエリ言語
  • クエリ言語の型を宣言するGraphQLスキーマ言語
  • Webクライアントとサーバーのためのアプリケーション層の仕様

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


歴史

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

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


主な仕様


何でないか

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

なぜGraphQLを使うのか

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

1. 単一リクエスト

効率的なデータ読み込み

オーバーフェッチを最小限に抑え、サーバーへのラウンドトリップを少なくする Facebookが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スキーマ言語

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

  """このポケモンの全国図鑑No."""
  number: String

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

  """このポケモンの重さの最大と最小"""
  weight: PokemonDimension

  """このポケモンの高さの最大と最小"""
  height: PokemonDimension

  """このポケモンの分類"""
  classification: String

  # ...
}

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

https://www.apollographql.com


3. 開発ツール

短期間での開発

クライアントアプリケーションの設計変更に対応するためのツールが提供されている 継続的デプロイ (CD) が背景


IDE - GraphiQL

h:600 GraphiQL

https://github.com/graphql/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