Web API を理解するためのノート

API とは?

概念の説明は他の場所でされているのでしない。RESTful API を使用して芸術の世界を探索するの内容から理解に役立つ説明を抽出する。

API はキッチンシンクのようなものである。キッチンシンクを使うとき「蛇口ひねると水が出る」とわかっていれば使用でき、水道管の構造を理解する必要はない。同様に API を使うとき、「このようにリクエストすればこのような結果が得られる」とわかっていれば使用でき、全体のアーキテクチャや裏側の細かな処理やデータベース構造を理解する必要はない。API を使えば機能の利用が簡単になる。貯水槽や水道管をつくったり、構造を理解しなくても使える。

例えば jQuery API を利用すれば、vanillaJS で書くと細かくて冗長になる DOM 操作のコードなどを簡略化されたコードで利用できるようになる。

API は 2 つのプログラムが通信して処理を行うためのインターフェースの仕様である。API はハンドシェイクである。ハンドシェイクは 2 つの装置がデータを送受信するために必要な通信ルールの取り決めである。

REST とは?

インターネットのあちこちに分散するプログラムが互いに通信しながら動作するシステムをどうやって実現するか?この問題を解決する方法の1つが REST である。REST では HTTP メソッドによってデータの取得、保存、削除などの基本操作を行えるようにプログラムを設計する。REST はインターフェースを統一するための設計の考え方である。

REST の原則に基づいて設計された API を RESTful API という。

API リクエストの方法

  • プログラム言語でリクエストを作成して送信する。(例:JS, PHP, Shell…)
  • Postmanなどの API プラットフォームを使用する。
  • ブラウザでリクエスト URL を入力する。
  • JMeter などの HTTP リクエストが行えるツールを使用する。

API を理解するための基本要素

1. エンドポイント

  • Route(ルート)と呼ばれる。
  • URL 形式である。
  • API 提供側からは URL が処理開始地点になるのでエントリーポイントと呼ばれる。

2. HTTP メソッド

同一のエンドポイントに 各 HTTP メソッドでアクセスし、メソッドごとに処理を分岐させる。RESTful であるためには、CRUD 処理と HTTP メソッドは以下のように対応する必要がある。

  • GET –> データ取得(R)
  • POST –> データ保存(C)
  • PUT –> データ更新(U)
  • DELETE –> データ削除(D)

プロトコルは HTTPS を使用すべき。HTTP で認証情報などを含むデータをプレーンテキストで送信すると盗聴されるリスクがある。だから HTTPS で暗号化されるようにするのが原則である。

3. HTTP ヘッダー

リクエストヘッダー

  • Authorization: [type] [credentials]
    • 認証のために HTTP リクエストヘッダーに情報が必要なことがある。
  • Content-Type: application/json;charset=utf-8,
    • クライアントから送信するデータの種類をサーバに伝えるため、リクエストヘッダーに必要な情報。
    • 本文が文字列ならデフォルトはtext/plainである。json を本文に入れて送信したいときはapplication/jsonを指定する。

レスポンスヘッダー

  • Access-Control-Allow-Origin: [origin]
    • クロスオリジンのリクエストをしてきたクライアント(ブラウザ)にリソースへのアクセスを許可するかどうかを伝える。CORS を行うかどうかを制御する。

4. ボディー(本文)

  • JSON のことが多い。

アクセス制御、認証

多くの API はアクセス制御の仕組みをもつ。

  • なぜ制限する?
    • 「セキュリティーのため。」「具体的には?」「…」
  • どうやって?
    • CORS
    • API キー
    • アクセストークン
    • 例:「1秒あたりのリクエスト数上限は 80 件以下」など。(これはゆるい方らしい)

オープンな API の例

認証が必要な API の例

認証の方法

  • HTTP 認証
  • API キー
    • 一般的によく使われる。
    • 傍受できれば誰でも使えるので本質的には安全ではない。
    • API キーで安全にアクセス制御するには?
  • Oauth 2.0
    • 承認と認証は違う?
    • アクセストークンを使う。トークンは有効期間や用途を制限できる。
    • 機密性の高いエンドポイントにアクセスする場合アクセストークンを使う方が安全。
    • 例えば、クーパーヒューイット API では、API ページでアカウント情報(ユーザー名、パスワード)を作成した後、API キーとトークンを作成する。リクエスト URL にトークンを含めて送信すると API の利用が可能になる。
    • アクセス トークン “と” キーの両方を作成するのはなぜでしょうか?
      • 回答中…

API 関連の典型的なタスクにはどのようなものがあるか?

  • 独自の API を開発する
    • ローカルで API を開発する
    • API を公開する
  • 既存の API を使用する
    • API ドキュメントを読む
    • 利用規約を確認する(データセットの著作権など)
    • 外部 API にリクエストをするための認証手続きをクリアする
      • API キーが必要か?
      • アクセストークンが必要か?
    • API を叩く
    • 得た結果を使用する
    • エラーハンドリング
  • API のテスト
    • テスト仕様書作成
    • テストデータ作成
    • テスト実施
      • Postman や Jmeter を使う。Jmeter は大量の HTTP リクエストを自動実行できる。

クロスオリジン制限、CORS

XML Http Request や Fetch API は同一オリジンポリシーに従う。クロスオリジンへのリクエストはブラウザの機能により制限されて基本的には失敗する。 これはセキュリティ上の仕様である。

クロスオリジンのリソースへのアクセス権を与えるようにブラウザに指示すればクロスオリジンへのリクエストができるようになる。そのためには、サーバー側でアクセスを許可するオリジンを明示的に指定する。その情報は HTTP レスポンスヘッダーのAccess-Control-Allow-Originに含める。

CORS(Cross Origin Resource Sharing)は、このようなドメインをまたぐ通信をサーバー側から明示的に許可するための仕組みである。

  • Origin はプロトコル+ドメイン+ポートで表される単位である。
  • クロスドオリジンリクエストをする時、ブラウザはOrigin:ヘッダーを追加し、サーバーに正しいと保証されたオリジンを伝える。
  • クロスオリジンリクエストで API を呼び出して利用するには CORS が有効である(サーバ側で許可している)ことが条件。
  • CORS をサポートする API とサポートしない API がある。
  • 認証手続きなしで API を利用できるケースは少ない。「API はブラウザから JS で呼び出して使えるもの」というわけではなく、条件をクリアしないと使えない API の方が多い。

CORS 参考

クロスオリジン制限を回避するその他の方法

  • JSONP。script タグを使う。
  • 同一オリジンのサーバサイドにリクエスト用プロキシを用意し、プロキシ経由でクロスオリジンのリソースにリクエストする。(ブラウザで実行しなければいいという認識でいいのか?)

クロスオリジンリクエストには単純リクエストと非単純リクエストがある

単純ではないクロスオリジンリクエストではプリフライトリクエストをメインリクエストの前に行う。シンプルリクエストではないメソッド、ヘッダー情報をブラウザからのリクエストとして問題なく処理するために必要。

クロスオリジンエストは資格情報をもつ場合ともたない場合がある

API レスポンスの例外処理

HTTP レスポンスステータスコードを監視して例外をキャッチ、通知できるようにする。

歴史

従来の API は通信に SOAP、データに XML がよく使われていた。現在は通信に HTTP、データに JSON(または XML) を使うのが一般的になった。

API の開発、利用に使えるライブラリ、パッケージ

json-server

https://www.npmjs.com/package/json-server

  • 何?
    • 擬似的な Restful API サーバーをローカルに用意できるパッケージ
  • 何のため?
    • フロントエンド開発で素早くプロトタイプを行うため。擬似的な RESTful API を簡単に用意できるので、バックエンドに API がなくてもプロトタイプが作成できる。
  • どんな時使う?
    • フロントエンドで API を使用したいが、バックエンドの API 開発がまだできてない。
    • プロトタイプ作成のために Restful API のモックが欲しい。
  • どうやって使う?
    • db.json でデータベースのモックをつくり、API サーバーを起動して、ルートにリクエストする。

axios

https://www.npmjs.com/package/axios

JavaScript 開発で非同期に API を利用する場合に有効なライブラリ。Fetch API のデメリットが改善されている。fetch メソッドとの違いは以下。

  • 500 エラーなどのレスポンスも例外としてキャッチできる。Respose オブジェクトからステータスを読み取ったりしなくていい。
  • Response の結果を json()でパースとかしなくていい。
  • 非同期処理のコードが fetch メソッド使うよりも簡素化される。
  • Fetch はそのままだと基本的にはモダンブラウザでしか動作しないが、axios はそうではない。
  • その他の便利機能もある。
  • vue.js では axios 使うのがスタンダード?

疑問書き出し

  • 認証系の知識が足りていない。
    • API key
    • Oauth 2
  • Oauth2.0 の仕組みを説明できる? OAuth では、アクセス トークンを使用して承認コードを取得する承認コード付与に関する OAuth 2.0 プロトコルでは、トークンがアクセス コードと引き換えに交換されます。
  • 実際の業務システムでなにをする API を開発するか?これはバックエンドの開発プロジェクトで Laravel などの FW を用いて行う。管理サイトから API サーバにリクエストするとかは以前いたプロジェクトでやられていた。
  • 画像 URL を fetch()に渡すと、メトロポリタンは CORS で失敗する
    • メトロポリタンのサイトにオブジェクトのデータセットに画像は含まれないと書いてある。画像にアクセスできる URL はあるから fetch で画像取って来れないか?と思ったが、レスポンスにはAccess-Control-Allow-Originヘッダーがない。なのでクロスオリジンリクエストをブラウザが拒否する。他方、クーパーは画像データ取得できる。なぜならクロスオリジンリクエストがサーバー側で許可されているから。
  • Cookie
    • ドメインに属するクッキーという用語のイメージ
    • クッキーは通常いつ送信されるか
    • JS でリクエストを送信するときクッキーは送信されない。