GraphQLはRESTの後継者足りうるか？

会社でGraphQLについて調べる必要があって勉強したので、
その内容をこちらにも書きます。
レポートって感じです。

# GraphQLとは？
Facebookが開発したWeb APIのための規格です。
もともとはFacebook社内でAPIのレスポンスがイケてなかったのを改善したかったのが動機みたい
です。
詳しくは後述します。

# 歴史
もともとFacebookはFQL（facebook Query Language）という言語でWeb APIを運用していました。
詳細は不明ですが、SQL-likeな言語だったみたいです。

FQL
↓
2012年頃 GraphQL誕生
↓
2015年 GraphQL OSS化
↓
2018年11月
[GraphQL Foundation](https://graphql.org/)設立 ←イマココ！

# なぜ誕生した？
[GraphQL: A data query language
](https://graphql.org/blog/graphql-a-query-language/)
上記ブログにFacebookのエンジニアが書いた、GraphQLが生まれた経緯が書かれています。

モバイルアプリでAPIを叩くときに、アプリ側で欲しいオブジェクトグラフとAPIのレスポンスの構造に乖離がありました。

>Back in 2012, we began an effort to rebuild Facebook's native mobile applications.

>At the time, our iOS and Android apps were thin wrappers around views of our mobile website. While this brought us close to a platonic ideal of the "write one, run anywhere" mobile application, in practice it pushed our mobile-webview apps beyond their limits. As Facebook's mobile apps became more complex, they suffered poor performance and frequently crashed.

> As we transitioned to natively implemented models and views, we found ourselves for the first time needing an API data version of News Feed — which up until that point had only been delivered as HTML. We evaluated our options for delivering News Feed data to our mobile apps, including RESTful server resources and FQL tables (Facebook's SQL-like API). We were frustrated with the differences between the data we wanted to use in our apps and the server queries they required. We don't think of data in terms of resource URLs, secondary keys, or join tables; we think about it in terms of a graph of objects and the models we ultimately use in our apps like NSObjects or JSON.

> There was also a considerable amount of code to write on both the server to prepare the data and on the client to parse it. This frustration inspired a few of us to start the project that ultimately became GraphQL. GraphQL was our opportunity to rethink mobile app data-fetching from the perspective of product designers and developers. It moved the focus of development to the client apps, where designers and developers spend their time and attention.


【拙訳】
>話は2012年に戻り, 我々（Facebook）はFacebookの自社製のモバイルアプリをリファクタリングしようと試みました。

>その頃、FacebookのiOS/Androidアプリは、モバイル用WEBサイトのほとんど何もしていないラッパーでした。 このことは「write one, run anywhere」という純粋な理想に近かったのですが、実際にはそのことでモバイル用WEBサイトは限界を超えていました。Facebookのモバイルアプリが複雑化すればするほど、パフォーマンスは悪化し、よくクラッシュするようになりました。

> まず最初にモデルとビューの改善に着手したところ、最初にニュースフィードのAPIデータバージョンが必要なことに気づきました。その頃では、HTMLでしか提供されていませんでした。ニュースフィードのデータをモバイルアプリケーションで受け取るために、色々と方法を検討しました。RESTfulにサーバからデータとFQLテーブル（FacebookのSQLっぽいAPIです）による方法も含めて。しかし次第に、我々が望んでいるデータとAPIサーバが要求するクエリの乖離に不満を感じるようになりました。私達はデータを、URLだのセカンダリキーだの結合されたテーブルとして考えているのではなく、オブジェクトグラフ[^1]と結局アプリの中で使うことになるNSObjectsやJSONといったモデルとして考えていました。

> サーバ側でデータを提供するためにも、クライアント側でそれをparseするためにも、結構な量のコードが書かれていました。このフラストレーションから、モバイルアプリ開発チームの中の数人でプロジェクトが立ち上がって、最終的にGraphQLが誕生しました。
(以下略)

平たく言うと、GraphQLの誕生は、モバイルアプリ開発者がもっと使いやすいAPIサーバが欲しくて、新しい規約をつくったというのが経緯になります。
ではどのような仕様に仕上がったのでしょうか。

# GraphQLの仕様
SOAPやRESTと異なり、GraphQLはデータを記述する言語を持つ規格です。
「クエリ言語」と「スキーマ言語」の二種類があります。
クライアントサイドでサーバに対してクエリを発行する際に使うのがクエリ言語で、
サーバサイドでデータ構造を記述するのがスキーマ言語です。

なんでもいいのですが、[公式サイト](https://graphql.org/learn/)で紹介されている例を挙げます。
スキーマ言語の例は下記です。

```[]
type Query {
  me: User
}

type User {
  id: ID
  name: String
}
```

このスキーマに対して、

```[]
function Query_me(request) {
  return request.auth.user;
}

function User_name(user) {
  return user.getName();
}
```

クライアント側では、クエリ言語を下記のように投げます。

```[]
{
  me {
    name
  }
}
```

```[]
{
  "me": {
    "name": "Luke Skywalker"
  }
}
```
何が嬉しいって投げたクエリと戻ってきたレスポンスの形式が**ほとんど一致する**のが大きいですね。
RESTだとJSONが戻ってきたあとに、サーバが返してくるであろうデータの構造体を作っておいてそこにマッピングして、
そこから更に実際に使うデータを抽出する処理が必要でした。
GraphQLであれば、必要なデータだけとってくることが可能ですし、
（サーバ側が規約に従っている前提ですが）サーバ側の仕様変更でクライアント側のロジックを変えずにすみます。

# 参考
[「GraphQL」徹底入門 ─ RESTとの比較、API・フロント双方の実装から学ぶ](https://employment.en-japan.com/engineerhub/entry/2018/12/26/103000)

[^1]: とりあえず直訳しましたが、graph of objectsというのがピンと来ていないです