「Web API: The Good Parts」を輪読しました

2022-08-16

はじめに

以前,@kabe_239さんと「Web API: The Good Parts - O'Reilly Japan」を輪読したので感想と気になった点についてメモしていた部分を簡単に記事としてまとめておきたいと思います.

1章 Web APIとはなにか

WebAPIとは「HTTPプロトコルを利用してネットワーク越しに呼び出すAPI」のことです.APIとは”Application Programming Interface”の略で,ソフトウェアコンポーネントの外部インタフェース,つまりは機能は分かっているけれどもその中身の動作は詳しくはわからない機能のカタマリのことをいいます.

  • WebAPIを美しく設計する重要性
    • 設計の美しいWebAPIは使いやすい
    • 設計の美しいWebAPIは変更しやすい
    • 設計の美しいWebAPIは頑強である
    • 設計の美しいWebAPIは(開発者からの目線に対して)恥ずかしくない
  • 対象となる開発者の数とAPIの設計思想
    • LSUDs(large set of unknown developers):
      • パブリックにドキュメントを公開し,誰でも登録して使用できるため,誰が使うか分からない
      • さまざまなユースケースを想定してなるべく広く汎用的にしなければならない
    • SSKDs(small set of known developers):
      • 自社のスマートフォンクライアント向けのAPIなど,APIを利用する開発者が限られる
      • 特定の開発者やその先に存在するエンドユーザーにとって便利で使いやすいものでなくてはならない

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

APIのエンドポイントはURIであるから,覚えやすく,どんな機能を持つURIなのかが一目でわかるようなURIにする必要があります.これは通常のWEBサービス開発におけるURI設計と同様の考え方だと思われます.

  • 短く入力しやすいURI
  • 人間が読んで理解できるURI
  • 大文字小文字が混在していないURI
  • 改造しやすい(Hackableな)URI
    • ドキュメントを読まなくてもそのAPIのURIが何を行いたいのかすぐに考えることができれば,あまりドキュメントをみなくても開発に注力することが可能となる.
  • サーバ側のアーキテクチャが反映されていないURI
  • ルールが統一されたURI
    • ユニークな情報を取得するためのAPIに対して,クエリパラメータにユニークIDを含めてGETするか,パスにユニークIDを含めてGETするかのルールを統一するべきである.

Application-only authentication について書籍中に記述されていましたが,どのようなものに使用されるのかということについて理解が及ばず,たとえばTwitterの特定の人物に対するタイムライン埋め込みなどに使用されるのではないかと考えています.(例:はてなブログなどでIDやリンクを指定すると自動的に埋め込みなど?)

また,書籍中にはHATEOASというものについて記述されていたのですが,HATEOASでは,理解しにくかったURIについてもrel要素を見てどんなAPIの操作なのかわかるように設計することができるということなのではないかと考えています.

以下,HATEOAS参考文献

3章「レスポンスデータの設計」

レスポンスデータのデータフォーマットについて,JSON形式で返されるデータをよく触ることが多い気がしており,以前にもJSON形式で帰ってくるAPIを利用したことが幾度かありました.

  • Amazon のレスポンスデータフォーマットについて,現在はJSON形式になっている模様.(本ではXMLしか対応していないと記載)
  • 過去に楽天APIを利用した際のエンドポイントの書き方はクエリパラメータだった.
  • JSONPについて
    • JSONP (JSON with padding) は,クロスサイト環境で他のオリジンから JSON データを取得するために考案された仕組みであり,パディング部分に任意のコードを埋め込めるのではないかと考えられるため,クロスオリジンなどの脆弱性を起こす可能性があると感じられた.
    • JSONPに関するセキュリティの問題について以下のような記事を見つけた
    • JSONPを使用したくなる場面としてどのようなものがあげられるのだろうか?
      • 公式サイトのTwitterなど?(例:はてなブログなどでIDやリンクを指定すると自動的に埋め込みなど?)

レスポンスデータにIDのみを含めたJSONを返すのか,また,IDを含めた個人の情報を返すのかというデータの内部構造をそのAPIを利用する際に応じて考える必要があります.もしくはIDに付属する情報をクエリパラメータを使用し,レスポンスデータとして返す方法もあります.

そして,JSONデータの返し方には階層的に返す場合とフラットに返す場合があり,階層構造で返す場合はJSONのデータサイズが大きくなってしまうため,そういった観点からこうした不要な階層化はするべきではありません.

4章「HTTPの仕様を最大限利用する」

レスポンスヘッダで200を返すが,実はエラーとしてレスポンスデータが返されるような振る舞いを行っているAPIもあり,これはクライアントが正常にHTTPステータスコードを認識することが出来なくなるので,HTTPステータスコードに準ずるヘッダを返すべきです.

メールアドレスを検索するAPIで410コードを返す仕様では,メールアドレスの物理削除でも,なにかがあったこと自体は情報としてどうしても残ってしまうため,APIのリクエストでメールアドレスをボディに付与し叩いてしまった際に410が出ると問題になるということから,個人情報保護などの観点から問題を指摘されます.

プロキシサーバがオリジンサーバでは変わってしまった情報を返してしまうことを防ぐ方法には以下の方法があります.

  • 期限切れモデル:キャッシュの期限が切れたら再度アクセスして情報を取得する
    • しばらく情報に変動がない者に対して有効である
  • 検証モデル:今保持しているキャッシュが最新であるかどうか問い合わせて,更新されている場合のみ取得を行う
    • 情報が常に変動する可能性がある者に対して有効である

クロスオリジンリソース共有(CORS:Cross-Origin Resource Sharing)とは,リクエスト側でOriginヘッダにアクセス元を指定し,サーバ側で許可できる生成元であればアクセスを許可し,そうでなければ403エラーを返します.
セキュリティ上,どこから読まれても問題ない場合は Access-Control-Allow-Origin ヘッダに * を指定すると,どこからでも読み込めることを明示することができます.

また,”X-”という接頭辞について,独自に定義したものであり,付けても付いていなくても良いが,それ以降の独自ヘッダについて統一する必要があります.

5章「設計変更をしやすいWeb APIを作る」

APIのバージョンの指定方式についての違いなどについて,パス,クエリ,メディアタイプなどに指定することも可能となっています.それ以外にも,セマンティックバージョニングがバージョニングの方法として多く知られています.

クライアントに合わせたアプリケーション向けにインターフェースを変換するオーケストレーション層がサーバに存在します.多数のクライアントに合わせたインターフェースの乱立により,複雑になる可能性が示唆されるのではないか?と考えています.こういった場合,実装イメージが難しいのではないかと考えています.

6章「堅牢なWeb APIを作る」

サーバ・クライアント間での情報の不正入手を防ぐために,WebAPIでは以下のことに気を付ける必要があります.

  • セッションハイジャックによりセッション情報を盗み,その人のIDでサービスを利用する
  • HTTPSによるHTTP通信の暗号化により防ぐ
  • 中間者攻撃による危険性もあるため,完全に安全であるとは言えない

また,ブラウザでアクセスするAPIにおける問題として,XSS,XSRF,JSONハイジャックや,パラメータの改ざんやリクエストの再送信などにおける悪意のあるアクセスへの対策などを行う必要があります.そして,セキュリティ対策のためのヘッダやユーザーごとのアクセスを制限する必要があります.

終わりに

WebAPIとはどのようなものか,具体的に,そしてWebAPIを実際に実装する際に気を付ける点などについて勉強することができ,とても良い書籍だと思いました.若干古い内容が含まれていたため,自分で新しい内容を調べつつ読み進めていくと良かったと思われました.

この本を読んだ後で,セキュリティに関して勉強不足を感じる部分があるなと感じてしまったため,「Webブラウザセキュリティ ― Webアプリケーションの安全性を支える仕組みを整理する - 米内貴志」を読みたいと思いました.

Share