GraphQL勉強会発表資料(補足)

2017.6.7(水)に社内で開催したGraphQL勉強会の発表資料の補足ページです。

**発表資料**
[GraphQL勉強会 2017.6.7 // Speaker Deck](https://speakerdeck.com/notakaos/graphqlmian-qiang-hui-2017-dot-6-7)

# FAQ

## Q1. GraphQLってなんなの？
**A1. GraphQLはクライアントからサーバーへの問い合わせに使用するクエリー言語(仕様)です**

- プログラミング言語ではなく、クエリー言語
  - アプリケーションレイヤー
  - 一種のDSL
- クライアント/サーバーアプリケーションのデータモデルの機能と要件を説明するためのもの
- 2012年にFacebookによって作成され、2015年までFacebook社内で使用されていた
  - 2015年にFacebookが一般公開した
  - 現在仕様の標準化を目指しており、Draft RFCが公開されている
    - https://facebook.github.io/graphql/
- GraphQLが提供するもの
  - 統一言語、タイプシステム、API仕様取得機能

## Q2. GraphQL を使うと何が嬉しいの？
**A2. メリットは以下の通りです**

1. クライアントアプリケーションが必要とするデータを1回のリクエストで取得できるようになる
  1. モバイルネットワークで特に有効
  2. 複数のデータソースを1回のリクエストでまとめて取得できる
2. APIのエンドポイント1つだけ、1つのエンドポイントで様々なリクエストに対応できる
  1. さまざまなクライアントに1つのエンドポイントで対応でき、プラットフォーム、クライアントアプリケーションのプラットフォームやバージョンの影響を受けない
3. クライアントアプリケーションからサーバーにリクエストを投げる際に、統一されたインターフェースが提供されているので、クライアント/サーバーそれぞれの実装に影響を受けずに開発を進めることができる
4. タイプシステム(型)とセルフドキュメンテーション
  1. タイプシステムのお陰でクエリのバリデーションが容易になる
  2. 型定義自身がドキュメントとなるため、別途ドキュメントを用意する必要がなく、またドキュメントとAPIの仕様が異なるという現象を防ぐことができる
5. GraphQLの開発をサポートするツールの恩恵を受けられる
  1. GraphiQL が優秀

## Q3. 逆に GraphQL のデメリットは？
**A3. デメリットは以下の通りです**

1. サーバーサイドの実装が大変
  1. RFCに従って一からサーバープログラムを自作するのは容易ではない
  2. プロジェクトで使用する場合は、すでに幾つかサードパーティ製の実装があるので、それを使用するのがよい
2. クライアント側で、何のデータが必要なのかを「すべて」明示する必要がある
  1. 1回のリクエストでのコード量は増加する
  2. とはいえ、アプリケーションがどのデータを使用しているか明示されるため、後で見た時にわかりやすく拡張し易い
3. 文献が少ない
  1. 英語のドキュメントがほぼ(2017.6.7現在)
4. パフォーマンス最適化のベストプラクティスがない
  1. リクエストの形が毎回変わる可能性があるのでキャッシュが(REST APIに比べて)難しい

## Q4. GraphQLを実際に使ってみたい！
**A4. 手っ取り早くを試すなら以下のサービスがよいです！**

- GitHub GraphQL API - https://developer.github.com/v4/
- SWAP - http://graphql.org/swapi-graphql/
- Idobata GraphQL API  - https://idobata.io/ja/api

## Q5. ユーザー認証はどうやるの？
**A5. 基本GraphQLは認証には関与しないので、別に考える必要があります**

- GraphQLの中で認証することも、既存のAPI認証の仕組みをそのまま使用することもできる
- 参考: https://idobata.io/ja/api

## Q6. GraphQL実装はどのようなものがありますか？
**A6. 以下のページにリストアップされています**

- http://graphql.org/code/
  - Server
    - JavaScript (Node.js)
      - GraphQL.js https://github.com/graphql/graphql-js/
      - express-graphql https://github.com/graphql/express-graphql
      - graphql-server (Apollo) https://github.com/apollostack/graphql-server
    - Ruby
      - graphql-ruby https://github.com/rmosolgo/graphql-ruby
    - Python
      - Graphene https://github.com/graphql-python/graphene
    - Scala
      - Sangria https://github.com/sangria-graphql/sangria
    - Java
      - graphql-java https://github.com/graphql-java/graphql-java
    - Clojure
      - alumbra https://github.com/alumbra/alumbra
      - graphql-clj https://github.com/tendant/graphql-clj
    - Go
      - graphql-go https://github.com/graphql-go/graphql
        - 参考実装
      - graphql-relay-go https://github.com/graphql-go/relay
      - neelance/graphql-go https://github.com/neelance/graphql-go
        - 現在アクティブな実装
    - PHP
      - graphql-php https://github.com/webonyx/graphql-php
        - 参考実装のポート
      - graphql-relay-php https://github.com/ivome/graphql-relay-php
    - C# / .NET
      - graphql-dotnet https://github.com/graphql-dotnet/graphql-dotnet
      - graphql-net https://github.com/ckimes89/graphql-net
    - Elixir
      - absinthe https://github.com/absinthe-graphql/absinthe
      - graphql-elixir https://github.com/graphql-elixir/graphql
  - Client
    - 任意のHTTP Client
      - GraphQLのクエリーを投げるだけであれば既存のHTTP Clientがそのまま使える
      - cURL / jQuery.ajax / fetch API / etc.
      - 既存のREST APIと同じようにCallするだけ
    - JavaScript
      - Relay https://facebook.github.io/relay/
      - Apollo Client http://dev.apollodata.com/react/
      - Lokka https://github.com/kadirahq/lokka
    - Swift / iOS
      - http://dev.apollodata.com/ios/
    - Java / Android
      - https://github.com/apollographql/apollo-android
    - C# / .NET
      - https://github.com/bkniffler/graphql-net-client


## Q7. GraphQLを理解するポイントは？
**A7. 以下がポイントになります。**

1. REST APIと違いすべてのリクエストはPOSTになる
  1. 例外的に、型情報を取得するもののみGET
  2. それ以外はすべてPOST
2. 「クエリー(Query)」と「ミューテーション(Mutation)」の2種類がある
  1. クエリーは副作用を伴わないリクエスト
    1. REST APIのGET相当
  2. ミューテーションは副作用を伴うリクエスト
    1. REST APIのPOST/PUT/PATCH/DELETE等
3. CQRS( Command Query Responsibility Segregation コマンドクエリー責務分離)
  - データの読み込みと書き込みは別のものとして考える
4. GraphQLのレスポンススピードはqueryの中で解決が一番遅いものに引っ張られる
  - 早く取得したいものと遅いものをそれぞれ別のクエリで取得すると良い


# 参考文献
- GraphQL公式サイト - http://graphql.org/
- GraphQL RFC (Working Draft) - http://facebook.github.io/graphql/
- Apollo - https://www.apollodata.com/
- GraphQL San Francisco (San Francisco, CA) | Meetup - https://www.meetup.com/ja-JP/GraphQL-SF/?chapter_analytics_code=UA-74643563-3
- GitHub GraphQL API - https://developer.github.com/v4/