【読書メモ】Web API The Good Parts

# はじめに
オライリージャパンさんの「Web API The Good Parts」を読んだので、自分用のメモ程度に記録していきます。

https://www.oreilly.co.jp/books/9784873116860/

# 1章：Web APIとは何か

本書ではWeb APIを「HTTPプロトコルを利用して、ネットワーク越しに呼び出すAPI」のことを指しています。
もう少し具体的に言うと、URIにアクセスすることで、サーバ側の情報の書き換え・取得などを行うことができるウェブシステムで、プログラムからアクセスしてそのデータを機械的に利用するためのものです。

現在APIを呼び出した結果として返ってくるデータの形は、多くがJSONかXMLです。
この返ってきたデータをそのまま使うのではなく、加工した上でブラウザなどに表示しています。

筆者としては、自前のサービスを持っているのであれば、APIを公開するべきだと言っています。
理由として、有名でないサービスであれば悪さをしようとする人は少なく、寧ろ情報を有効活用して付加価値をつけてくれる人が出てくるかもしれないためであり、有名はサービスであれば運用に気をつけるべきではあるものの、より多くの人が注目してくれて場合によってはユーザーの囲い込みにつながる可能性もあるためです。

そして、本書の主題は「美しいWeb APIを設計する方法について考えること」です。

Web APIを美しく設計する重要性として、以下の4つを説いています。
1. 設計の美しいWeb APIは使いやすい
1. 設計の美しいWeb APIは変更しやすい
1. 設計の美しいWeb APIは頑強である
1. 設計の美しいWeb APIは恥ずかしくない

また、本書ではLSUDs（large set of unknown developers:未知のたくさんの開発者）とSSKDs（small set of known developers:既知の少数の開発者）と言う言葉が用いられます。
これは、誰が使うかわらかないLSUDs向けのAPIと、特定の開発者などのSSKDs向けのAPIでは、設計思想なども異なる部分があるためです。

# 2章：エンドポイントの設計とリクエストの形式

エンドポイントとはAPIにアクセスするためのURIのことです。
エンドポイントの基本的な設計原則は「覚えやすく、どんな機能を持つURIなのかが一目でわかる」です。
具体的には、以下の要素が大切になります。
- 短く入力しやすいURI
- 人間が読んで理解できるURI
- 大文字小文字が混在していないURI
- 改造しやすいURI
- サーバ側のアーキテクチャが反映されていないURI
- ルールが統一されたURI

「URIの中でどんな単語を使うのが良いのか」などに迷った場合は、「Programmable Web」のAPIのディレクトリを見ると、多くのAPIが登録されているため参考になるそうです。

ただ、基本的にはHTTPメソッドと組み合わせて、以下のように作成したら良いとのことです。
ホスト名も「api.hogehoge.com/v1」などが一般的とのことです。

|機能|URI|HTTPメソッド|
|---|---|---|
|ユーザーの一覧取得|http://api.hogehoge.com/v1/users|GET|
|ユーザーの登録|http://api.hogehoge.com/v1/users|POST|

加えて、上記のような「サーバ上のリソースにアクセスするAPI」のURIは、以下の点に気をつけると良いとのことです。
- 複数形の名詞を利用する
- 利用する単語に気をつける
- スペースやエンコードを必要とする文字を使わない
- 単語を繋げる必要がある場合はハイフンを利用する

私が過去に設計したAPIのURIを思い返すと、「複数形の名詞を利用する」が統一できていなかったような気がしてきました。
「複数形の名詞を利用する」と言うのは、DBのテーブルに複数形が使われるのと同様、usersなどは「集合」を表しているため、複数形の方が適切であろうという考えです。

たくさんあるデータの一部を取得する際には、取得位置を相対位置で決めるのか、絶対位置で決めるのかを考える必要があるとのことです。これは、取得中にデータ更新が挟まった場合や、大量のデータがある場合の計算量の問題に対処するためです。
私が過去に設計したAPIのURIを思い返すと、ここの意識は正直なかったので、これまた良い学びでした。

クエリパラメータとパスの使い分けに関しては、以下の基準を持つと良いとのことです。
- 省略可能かどうか
    - この場合はクエリパラメータが適しています
- 一意なリソースを表すのに必要な情報かどうか
    - この場合はパスが適しています

また、APIに必要以上アクセスすることは効率が悪いため、レスポンスデータ構造もしっかりと考える必要があります。
「１スクリーン１APIコール、１セーブ１APIコール」と言う言葉もあるそうです。

# 3章:レスポンスデータの設計

レスポンスデータの形としては基本JSONとし、必要に応じてXMLにも対応する形が良さそうです。
理由としては、JSOnがデファクトスタンダードになっているためです。

レスポンスデータの内容としては、なるべく過不足のないデータであることが好ましいです。
（1つの作業を完結するために複数回のAPIコールが必要となるAPIのことを「ChattyなAPI」と呼ぶそうです）
一方で、LSUDs向けのAPI、つまり広い対象に公開するでは「過不足のないデータ」が難しい場合もあります。
その場合は、以下のようにクエリパラメータを使用して、取得したい情報を指定する方法もあります。

例：http://api.hogehoge.com/v1/users/123?fields=name,age

また、配列で取得したデータに続きがある場合は、その「続きがある」と言う情報をレスポンスに含めてあげる必要があります。本書では「hasNext」と言う名前で返してあげるのも良いと書いてありました。

そのほかにも、性別データを例にしたデータの取り扱いなどデータフォーマットのお話や、エラーコードやエラー詳細をどのように含めるのかのお話も記載されています。

私がこの章でハッとさせられたのは「ステータスコードはレスポンスボディに含めるべきではない」ということです。
話の流れとしては、まず以下のようなレスポンスを設計したとします。

```
{
  "header": {
    "sttus": "success",
    "errorCode": 0,
  },
  {
  "response": {
    ・・・実際のデータ・・・
  }
}
```

上記のように全てのデータを同じ構造で包むことを「エンベロープ（封筒の意）」と言います。
そして、上記の「header」に対応する部分は不要ということです。
なぜならば、Web APIは基本的にHTTPを利用しており、HTTPのヘッダでステータスコードなどを表すことができるからです。
レスポンスボディにステータスを記載する方法を取ると、「HTTPヘッダのスタータすは400なのにレスポンスボディのステータスは200」みたいなことが起きかねません。
また、レスポンス内容も本当に必要な情報に絞ることができるなどのメリットもあります。

私は過去の実装を思い返すと、API設計書のレスポンスデータの中にステータスコードを含めてしまっていた気がしました。
今回この本を読み理由を知ることでとても納得したので、次回以降気をつけようと思います、、！

# 4章：HTTPの仕様を最大限利用する

Web APIはHTTP上で通信を行うので、HTTPの仕様を理解して利用した方が良いということです。
前章の私の気づきとして挙げたステータスコードの話もありますが、キャッシュやメディアタイプなどのお話も紹介されています。

例えば、メディアタイプはContent-Typeで指定しますが、これは非常に重要なことです。
なぜなら、クライアントの多くはContent-Typeの値を使ってデータ形式を判断しており、その指定を間違えるとクライアントが正しくデータを読み込めなくなることがあるためです。

私は正直これまで開発する中であまり気にしたことがなかったのですが（セキュリティ関連の修正をしたときは気にしましたが）、ここも今後は気にして開発しなくてはという学びになりました。

# 5章:設計変更をしやすいWeb APIを作る

Web APIは公開後もずっと公開状態が続くものです。
しかし、何らかの理由により仕様の変更や廃止をすることもあります。

例えば仕様変更。サービス提供側としては「仕様変更しない」が理想ではありますが、なかなかそうもいきません。
そのため、以下の例のように、URIにバージョンを含めておくことが良いと考えられます。

例：http://api.hogehoge.com/v1/users

そうして、URIを変えなければならない仕様変更が生じた場合には、「v1」を「v2」に変えたURIを用意し、一定期間は「v1」と「v2」を並行して走らせ、一定期間後に「v1」を廃止するなどします。

ここでも私の振り返りになりますが、過去にAPI設計をした際にバージョン情報をURIに含めていなかったなと猛省しました。

また、廃止する場合に関してはTwitterのケーススタディが掲載されており、具体的にどのような手順でユーザーへの周知など廃止へのステップを進めたら良いのかが分かりました。

さらに、多くの方へ向けて公開しているLSUDsのWeb APIは、人によっては「不必要なデータまで取ってくることになってしまう」のような場合があります。
これは仕方ないことでもあるのですが、これに対する解決策をNetflixの実装を例に解説されています。
具体的には「オーケストレーション層」という、クライアントのアプリとNetflix社が公開しているWeb　APIの間に、クライアント側が作成するカスタマイズされたWeb APIを挟むことで、各クライアントに使い勝手の良さを提供しているそうです。

# 6章：堅牢なWeb APIを作る
最後にセキュリティのお話です。
Web APIはHTTPを通じて公開されますし、機械的なアクセスを前提としているため、セキュリティに気をつける必要があります。

本書では具体的に以下3つのセキュリティの問題が説明されています。
- サーバとクライアントの間での情報の不正入手
- サーバの脆弱性による情報の不正入手や改ざん
- ブラウザからのアクセスを想定しているAPIにおける問題

サーバとクライアントの間の対策としてはHTTPSによる通信の暗号化、ブラウザからのアクセスに生じるXSSやXSRFへの対策としては、レスポンスヘッダやJSON文字列のエスケープ、トークンの使用などが挙げられています。

また、上記は第三者からの攻撃への対策ですが、悪意あるユーザーへの対策として、アクセスできないはずの情報はサーバ側でしっかりチェックすることや、偽装されたリクエストを想定した対策をすることが述べられています。

またそのほかにも、実際のサービスを実例としたHTTPヘッダの使い方や、レートリミットの掛け方などが紹介されています。

ここまで外部に広く公開する用のAPIを設計したことはないのですが、講じるべき策とその方法を知ることができ勉強になりました。

# 最後に

メモ程度にですが、初めて読んだ本の内容をQiitaにまとめてみました。