概要
下記の2冊の読書メモ。
- 『Web API: The Good Parts』(オライリージャパン、2014)
- 『RESTful Webサービス』(オライリージャパン、2007)
読みながら気になった点を書いていく。個人的な読書メモなので、網羅的ではない。
全体的な感想
『RESTful Webサービス』
『RESTful Webサービス』のほうは2007年とあって、内容に時代を感じた。RPC、XML、SOAP、WSDLなど、今ではレガシーと捉えられる技術についても触れられている(過去の技術としてではなく)。
書かれた時代背景を知るために、二箇所引用しておく。
現代の「Web サービス」のほとんどは、
Web とは何の関係もない。Web の単純さに反して、それらは COM や CORBA のような分散オブ
ジェクトアクセスのための重量級のアーキテクチャを採用している。(『RESTful Webサービス』はじめに)
ほとんどの Web サービスは XML ドキュメントを返すが、JSON フォーマットの文字列として直
列化された、単純なデータ構造(数値、配列、ハッシュなど)を返す Web サービスが増えてきてい
る。(『RESTful Webサービス』P.46)
ただし、下記の通り、RESTについてあらためて学び直すには良い教材である。
本書は、「RESTful」な Web サービスのベストプラクティスとは何かを示す初の書籍である。混乱や憶測を打開し、伝承や暗黙的な認識を具体的なアドバイスと置き換える。(『RESTful Webサービス』はじめに)
かの論文とこの本をじっくり読めば、RESTの理論的な部分はだいたい分かると思う。
とくに、ROA(Resource-Oriented Architecture)を知ることで、RESTの理解を深めることができた。ROAは、「RESTful Web サービスによって問題を解決する手段」(P.83)であり、第4章で詳しく解説されている。
『Web API: The Good Parts』
「本書は現実的な Web API を「美しく」設計することに主眼を置いている」(P.17)とあるように、利用者が使いやすく、また開発者にとって保守性の高いWeb APIの設計方法やベストプラクティスが書かれている。
世間的にメジャーなWeb APIの設計の比較や例示が多いので、実践的ですぐにでも取り入れることができる内容いなっている。
今どきのWeb APIは、何らかの形でRESTの影響を受けているし、この本で勧められているベストプラクティスもRESTの考え方がベースになってものが多い。
ただし、「REST という言葉にこだわりすぎない」(P.18)と筆者が言うように、RESTを取り入れながら、あくまで「美しいWeb API」をつくり上げるための方策が現実的な目線で書かれている。
読書メモ
前置きが長くなったが、ここからは書籍を読みながら気になった点、勉強になった点、心にとめておきたい点などを記していく。
『RESTful Webサービス』
Webサービスアーキテクチャの分類(P.13)
REST以外あまり知らなかったので、勉強になった。
- RESTfulリソース指向アーキテクチャ
- 「Webのようなサービスのこと」(P.14)
- 言葉不足でよく分からない
- 「この種のサービスを、リソース指向と呼ぶことにする」(P.14)
- 「RESTful アーキテクチャでは、メソッド情報は HTTP メソッドに含まれる。リソース指向アーキテクチャでは、スコープ情報は URI に含まれる。」(P.14)
- 疑問:RESTfulアーキテクチャは、リソース指向アーキテクチャと別物?(RESTの要件の1つにリソース指向もあるイメージだったが)
- 「Webのようなサービスのこと」(P.14)
- RPCスタイルのアーキテクチャ
- 「データが含まれたエンベロープをクライアントから受信し、同じようなエンベロープを返送する。メソッド情報とスコープ情報はエンベロープに含まれるか、エンベロープのラベルに含まれる。」
- 疑問:エンベロープは、POSTするときのBodyとして表現される?
- いろいろ分からないけど、RPCに触れることは当分なさそうなので放置
- 記憶があやふやだけど、Amazonか何かのAPIで、RESTに則らない新しい設計として、URLはすべて同じでBodyに入れられたJSONですべて表現するものがあった気がするが、RPCへの回帰といえるのかな
- RPCは、リモートサーバの処理を呼び出す行為や技術、といった認識だった
- 疑問:RPCにエンベロープという概念は含まれている?特定の仕様は存在する?
- 疑問:エンベロープは、POSTするときのBodyとして表現される?
- 「データが含まれたエンベロープをクライアントから受信し、同じようなエンベロープを返送する。メソッド情報とスコープ情報はエンベロープに含まれるか、エンベロープのラベルに含まれる。」
- REST-RPCハイブリッドアーキテクチャ
- RPCを使いつつも、リソース指向やHTTPメソッドの活用など、REST的な要素を含むアーキテクチャ
- 筆者が考えた言葉とのこと
WSDL, WADL(P.21)
- 疑問:Swaggerとの違いは?
- サービスを記述する言語の話は、P.25にも少しでてくる
REST、RPC、SOAP(P.22)
- 「RESTfulアーキテクチャの主な競争相手はRPCアーキテクチャであり、SOAPなどの特定のテクノロジではない」
- RPCとSOAPが分かっていないので、理解できなかった
- このページの分類が分かりやすかった。(ただし内容を判断できる知識もないので参考程度に)
- どこかに、「RESTはHTTPに依存しない」とあったので、RESTfulアーキテクチャはもっと抽象的な概念だと言いたいのかも
- RPCとSOAPが分かっていないので、理解できなかった
RESTの特徴(P.83)
- 「スコープ情報(サーバがどのデータを送信するか)はURIに含まれる。これはアドレス可能性の原理である。」
- 「メソッド情報(サーバーがデータをどのように処理するか)はHTTPメソッドに含まれる。HTTPメソッドの数は限られており、それらの機能は周知のものだ。これは統一インターフェイスの原理である」
リソース指向アーキテクチャ(ROA)(P.83)
- 「RESTはアーキテクチャでなく、一連の設計条件」(P.84)
- たしかRESTの論文では、「こういう条件を満たしていればRESTである」といったものだった気がする(記憶があいまい)
- 「RESTはきわめて一般的な設計条件であり、特にWebと結び付いているわけではない。RESTに関するもので、HTTPの仕組みやURIの構造に依存するものは何もない」
- 本当か。URIやHTTPのメソッドとRESTは結び付いているが、それは依存しているとはいわない?たしかにHTTPの細部と密接に依存していたりはしないが。
- (このあとで、統一インタフェースの話がでてきて納得した)
- 本当か。URIやHTTPのメソッドとRESTは結び付いているが、それは依存しているとはいわない?たしかにHTTPの細部と密接に依存していたりはしないが。
- なぜ新しく「リソース指向」という言葉をつくるのか。「REST」ではダメなのか。
- ↑で書いたようにRESTは一般的な設計条件を指すが、筆者はWebと強い関連があるアーキテクチャとして論じたい
- また、RESTの定義には空白の部分が多く、実装者たちが慣習で補っている状況。その空白を明確にするのに同じ「REST」という言葉をつかうのは公正でない。
- 疑問:本当に「公正」でないのか。「おれのかんがえた最強のREST」みたいな話になる恐れはない?
- 「REST」という用語をつかうと「ナードの宗教戦争」に巻き込まれる
- つまり、従来の「REST」を筆者の理念をもって、Webの文脈の中で解釈するのに、「REST」ではない新しい用語を用いたほうが適切、というスタンスらしい
SOAの特性(P.83)
- アドレス可能性、ステートレス性、接続性、統一インタフェイス
リソースとは何か(P.85)
- 「リソースとは、それ自体を参照するに値するほどの重要性を持つもの」
- 「通常、リソースとは、コンピュータ上に格納することができ、一連のビットで表せるもの」
- リソースがリソースであるための条件は、「リソースは少なくともURIを1つ持っていなければならない」(P.86)
URI
- URIは記述的であるべき(P.87)
- 疑問:「記述的」とは、利用者が読んで意味を理解できるということ?
- URIは構造的でなければならない(P.87)
- 疑問:「構造的」とは、左から右にいくにしたがって、情報が詳しくなること?
- たとえば、
http://www.example.com/sales/2004/Q4
(P.87)のように - 「記述的」という言葉とあわせてもう少し説明して欲しかった
- たとえば、
- 疑問:「構造的」とは、左から右にいくにしたがって、情報が詳しくなること?
アドレス可能性(Addressability)(P.89)
- 「アプリケーションがそのデータセットの重要な部分をリソースとして公開する場合、そのアプリケーションはアドレス可能である。」(P.89)
- 「リソースは URI を通じて提供されるため、アドレス可能なアプリケーションは提供可能な情報ごとに URI を公開する」(P.89)
- Webサイト上の情報がリソースという形で表され、そのアクセスするパスが一意に表現される(どの利用者にとっても同じ)のが、アドレス可能性
- 逆にアドレス可能性をもたないシステムとして、Gmailがあげられている。ユーザは、
https://mail.google.com/
のURIのみを目にするからだ- cf. Ajax
ステートレス性(P.91)
- 「すべてのHTTPリクエストが完全に分離していること」(P.91)
- cf. FTP
- グーグルの検索は、
start=10
のようなクエリパラメータを付与する。- 「RESTfulとは、状態をクライアント側で維持し、それを必要とするリクエストごとにサーバーに送信しなければならないことを意味する。」(P.94)
- 「状態」を「アプリケーション状態」と「リソース状態」にわけているところが分かりやすかった
- アプリケーション状態とは、クライアント側で維持されるもの(さきほどの
start=10
など) - リソース状態とは、サーバー上で維持されるもの(Cookie)
- アプリケーション状態とは、クライアント側で維持されるもの(さきほどの
接続性(P.100)
- リンクを持つという特性
- リンクは、現在の状態から関連する状態へ移行する方法を示す
- リソースを相互に接続すると、Webサービスの使いやすさが増す
- cf. RPCスタイルのサービス(接続性を持たない)
統一インタフェース(P.101)
- HTTPメソッドのこと(GETやPOSTなど)
- 重要なのは、HTTPが定義する特定の統一インタフェースを使用することではなく、すべてのサービスがHTTPのインターフェイスを同じ方法で使用すること(P.109)
- 同じ方法でというのがポイントだと思った
8.1 リソース思考の基礎(P.223)
クライアントはリソースに直接アクセスすることができない。Web サービスはリソースの表現として、リソースに関する情報が含まれた特定のデータ形式のドキュメントを提供する。リソースとその表現との違いは、静的な Web サイトの場合は少し理論的で、リソースはクライアントに文字どおりに送信されるディスク上のファイルにすぎない。(P.224)
- 疑問:「リソース」と「表現」の違いがよくわからない。
- リソースはデータそのもので、表現はそれを例えばJSONの形式で表し、必要な付加情報を付け加えたようなもの?つまり、データをラップしたようなイメージであっている?
8.6.3 POSTのオーバーロード(P.228)
- 「POSTには、リソースを小さなRPCスタイルのメッセージプロセッサに変換するという用途もある」
- 「オーバーロードされたPOSTリクエストを受け取るリソースは、追加のメソッド情報の入力表現を読み取り、何らかのタスクを実行することができる。」
- 疑問:「POSTのオーバーロード」のイメージがはっきりと掴めない。
- POSTはクライントが任意のデータをリクエストボディに含めることができるので、行いたい操作もリクエストボディに含めてしまえば柔軟な操作ができる、という意味だろうか。
- この場合でも「リソース指向」は維持すべきとのこと
8.7.3 統一インタフェースが重要である理由(P.231)
- 統一インタフェースによって課される制約により、HTTPの信頼性を向上させる
- GETとHEADの安全性
- PUTとDELETEのべき等
8.16 Cookieの問題(P.263)
Cookieが「ステートレス」という設計にマッチしないというのは分かる。
(そもそもステートレスなHTTPプロコトルに状態を持たせるためにCookieが導入されたという私の理解)
サーバ側でCookieの値を生成し、クライアント状態を管理するのはRESTfulではないという。
一部のブラウザベースのアプリケーションでは、Cookieはクライアントによって作成され、サーバーに送信されない。Cookieは単に、アプリケーション状態を表現やURIでサーバーに送信するための便利なコンテナにすぎない。これはきわめてRESTfulなCookieの使用法である。(P.263)
これは現実的な手法か。たとえば、ユーザのログイン状態の管理としてCookieを用いないことは可能か。
実際問題として、ユーザのログイン状態はどのように表現するのだろうか。結局、クライアントがキー的なデータを送り、サーバ側で検証する必要があるのではないか。
Cookieを使わないとすると、HTTPのヘッダやPOSTのBodyに入れることもできるが、Cookieの場合とやっていることは変わらない。
スケーラビリティの観点から、RESTではステートレスにすることを要件に入れているようだが、これはセッションIDのようなものをクライアントが送り、サーバ側がメモリに保持するデータと突き合わせるのを禁止しているということ?
IDではなくキーそのものを送ってしまえば、サーバのメモリ上で情報を持っておく必要もないので、問題はなくなる?(セキュリティ的にどうなんだろう)
また、ショッピングカートの場合は、カート内の情報をすべてのリクエストに含める?
というか、アプリケーションサーバのセッション情報の同期機構やKVSなどのデータストアがあって、スケーラビリティが確保できれば、ステートレスでなくても問題ない?
考えだすと切りがないので、いったんここらへんにしておく。。
参考になりそうなページ
- https://www.glamenv-septzen.net/view/1350
- https://ja.stackoverflow.com/questions/21539/%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E4%BF%9D%E5%AD%98%E3%81%99%E3%82%8B%E3%81%A8%E3%81%8D-%E3%81%AA%E3%81%9C-cookie%E3%81%A7%E3%81%AF%E3%81%AA%E3%81%8Fmemcached%E3%82%84redis%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E3%81%AE%E3%81%A7%E3%81%97%E3%82%87%E3%81%86%E3%81%8B
- https://www.machu.jp/diary/20080101.html
- http://katsu-tech.hatenablog.com/entry/2015/02/01/184121
12章RESTfulサービスのためのフレームワーク
- 「1章では、RESTがアーキテクチャではなく、アーキテクチャを検証するための手段であることを示した」(P.359)
- 何度も述べられていることだが、「REST」を端的に表現した言葉
- 「アーキテクチャを検証するための手段」とは、対象のWebサービスがリソース指向であるか、HTTPメソッドを有効に使っているか、ステートレスかなどを検証すること
- 何度も述べられていることだが、「REST」を端的に表現した言葉
『Web API: The Good Parts』
2.2.1 エンドポイントの基本的な設計
- 良いURI設計の原則は、「覚えやすく、どんな機能を持つURIなのかがひと目でわかる」(P.22)こと
- シンプルな表現だが、『RESTful Webサービス』にでてきた「記述的なURI」というのと同義かもしれない
- 「リソース指向」には限らないようだ。
- 良いURI設計は、RESTに則る必要はないという筆者の意見だろうか
2.4.4 単語をつなげる必要がある場合はハイフンを利用する
- ドット、アンダースコア、キャメルケースという選択肢もあるが、ハイフンがいい
- URIはハイフンつなぎになるので、一貫性がとれる
- ドットは階層を表現する。アンダースコアはURIで使えない
3.2 JSONP
- JSONをブラウザに渡す方法の1つとして取り上げらているが、この本だけでは理解できなかった。調べる。
3.3.3 データをフラットにすべきか
- Q.レスポンスはJSONで返すことになると思うが、値にオブジェクトもつかって階層構造とするか、それともフラットにするか。
- A.なるべくフラットにして、階層構造のメリットが大きいときはそうする
レスポンスは配列にするか(P.81)
- Q.たとえば、何かの一覧を取得したとき、オブジェクトの配列を返すか、オブジェクトでラップするか
- A.どちらでもよいが、筆者的にはオブジェクでラップするのを推奨
- わかりやすさ、レスポンスの形式の統一、セキュリティ
- A.どちらでもよいが、筆者的にはオブジェクでラップするのを推奨
3.4.3 日付のフォーマット
- Q.いろいろあるが、何が適切?
- A.RFC 3389がよい
- 特定の言語への依存がなく、必要なデータを全て含み、冗長性もないため
2015-10-12T11:30:22+09:00
- A.RFC 3389がよい
5.5 オーケストレーション層
- 1つのアクションを行うのに複数のAPIにアクセスしなければならない→使いにくい
- 「サーバ側の汎用的な API とクライアントの間に“ Client Adapter Code ”を実行する層を挟み、さまざまなデバイスに対応」(P.154)
- クライアントとAPIの中間に、環境による差異を吸収する「オーケストレーション層」を置く
- 結局、オーケストレーション層を各環境ごとに実装する必要がある気がするが…
- クライアントの実装者が大変か、サーバサイドの実装者が大変か、という話にならない?
- 結局、オーケストレーション層を各環境ごとに実装する必要がある気がするが…