「Final Object #0」参加記録
@koriym さんのトークイベント、Final Objectに参加してきました。 株式会社TRASTA さんで開催されました。
主にTwitterで実況してました。 @hgsgtk さんによるイベントの速記録も参考になりますので、併せてご参照ください。 なお、聞き逃した箇所は適宜上記ブログと『RESTful Web APIs: Services for a Changing World』(English Edition)から補っています。
~Opening
イベントの招待状にはタイトルと仙厓義梵の『◯△□図』だけが記載されていました。何を話すのか知らされないイベントというのは新鮮で期待を胸に参加しました。
オープニングでは@koriymさんの『◯△□図』の解釈と『指月布袋画賛』の紹介がされました。 曰く、円相(満月)が真理を表し、四角は普く拡散されている状態を表す。三角はその中間で不要なもをを削ぎ落とすなど真理に至るまでブラッシュアップされていく様を表しているとのこと。 イベントの副題である「Think, "Talk" and Code」が開発者としての真理であるCodeに至るためのTalkに主眼をおいた会であるという提示がされました。
REST
本イベントはRESTの真理に近づくためのトークイベントであることが宣言されます。 2014年のPHPカンファレンス関西での基調講演「全てを結ぶ力」、2015年PHPカンファレンス福岡での基調講演「全てを結ぶ力(2015)」のダイジェストからイベントは始まります。 普段使っているRESTについて、我々は本当に理解して使っているのか、「Nobody Understands REST or HTTP」とも言われるように、RESTを理解するのは難しい状態にあるというテーマが設定されます。
『メディア論』でおなじみのマクルーハンが「誰が水を発見したかは知らないが、それが魚でないことだけは確かだ」という言葉の紹介もありました。
Roy T.Fieldingによって展開されたREST論文をそのまま読むのは難しいので、『RESTful Web APIs: Services for a Changing World』(English Edition)の「Appendix C. An API Designer’s Guide to the Fielding Dissertation」を手がかりに理解をしていくという方針が示されます。
HyperMedia Style Web API
WebAPIの種類はいくつかあることが紹介され、今回のテーマであるRESTはRoy T. Fieldingが記すようにハイパーメディアスタイルに分類されることが紹介されます。
- トンネリング: SOAP
- オブジェクト: URIスタイル/CRUD
- ハイパーメディア: REST
- クエリスタイル: GraphQL
- イベントドリブン: メッセージ指向 -- リチャードさん来日イベント参照
Webアーキテクチャの4つの重要な特性
Roy T.Fieldingが論文の第4章で重要視しているWebを成功に導いたの4つの特性が紹介されます
低い参入障壁
FTPやTelnetなどのコマンドラインツールと異なり、Webブラウザはマニュアル不要で操作できる。 テキストエディタでオーサリング可能で、設置(デプロイ)も簡単にできる。
拡張性
サービスが変わり続けることができる 例えば、ファミコンのカセットは一度デプロイしてしまうとそれっきりなので、拡張性がないと言える。 GAFAのような帝国もHTTP,URI,HTML,Javascriptによってユーザーに合わせて変化し続けてきた。
分散ハイパーメディア
- クライアントには情報がなく、表現(プレゼンテーション)や制御情報はリモートにある。
制御情報がクライアントにある例は、テレビなどのリモコン。Webではformタグの中にPOSTする情報は全て書いてある。 スマホもUIの表現の中に何ができるかが仕込まれているといえる。
- データ(プレゼンテーションと制御情報)によってできることの指示を受け取る。それをデータ自体と同じように扱う。
例えば<a>
タグ。レスポンスデータの中にリンクという形で制御情報が含まれている。
- 安全な遷移と安全でない遷移
安全な遷移:リンクによるリソース間の遷移(GETメソッド) 安全でない遷移:リソースの状態を変更するような操作の提供(POST,PUT,DELETEメソッド) リソースの状態はシステム側がダイナミックに変更可能である。
- クライアントを壊さずにサーバーの動作を変えられる
URIを変更せずに変えられないなら拡張性がないといえる。 今日のWebAPIが犯しがち。
インターネット規模
- 無秩序なスケーラビリティ
全体を理解してなくても他のサービスが壊れない。 クライアントはサーバーのことを意識し続けなくて良いし、サーバーはリクエスト間の状態を保ち続けなくて良い。
- 独立した配備
自分が新しいページを追加することでWeb全体を破壊するようなことがなく、独立している。 マイクロサービスのイメージ
APIはWebではない
APIはWebに似ているが、意思決定に人間が介在しないAPIにはセマンティックギャップがある。 人間が読める文章で記述すれば(分散ハイパーメディアの特性を捨てれば)セマンティックギャップは無くなるが、拡張性、スケーラビリティを失う。
4つ全ての特性を網羅したWebAPIを構築するのは難しく、必要に応じて取捨選択する必要が出てくる。
例えば - 「インターネット規模」を捨てて、「低い参入障壁」「分散ハイパーメディア」以外の「拡張性」を選択する -- 全てのクライアントを一斉に更新できる、社内APIの場合はいいかもしれない。 - 「インターネット規模」,「低い参入障壁」を選択し、「拡張性」と「分散ハイパーメデイア」特性を捨てる -- 今日のWebAPIは大抵ここを選択している、
フィールディング制約(9の制約)
HTTPは仕様。RESTは制約。
4つのインターフェースの制約
リソースの識別
URI=リソースのID リソース状態が変更されてもURIに変更は発生しない。 単一のURIに多くのリソースが含まれるのは良くない。 レストランサイトの例 - 営業時間、メニュー、場所は全て別々のリソースで持つべき。 - サイトの右下に地図があるよというのは人間に向けた説明であって、コンピュータには認識できない。
表現によるリソース操作
表現可能なものはなんでもリソースといえる。 - ペットボトルそれ自体は送れないが、画像や仕様(大きさ、素材など)は送れる - 表現の実態はバイト列で、ネットワーク越しに送ることができる
標準化されたHTTPメソッドのセット(GET/POST)を使用してリソースを操作できる。
自己記述的メッセージ
メディアタイプなどメッセージの解読に必要な情報はリンクヘッダ, content-type, プロファイルへの参照に書かれている。 情報をキャッシュする必要があるか、情報がいつまで有効かを決めるのはサーバー。クライアントで決めるのはRESTではない。
HTTPの仕様では以下の失敗があった。 - 1.0: Hostヘッダーがない -> 1.1で解消 - 1.1 どのリクエストできたメッセージかわからない。
Halだと表現できるのでBEAR.SundayではHalを採用した。
ハイパーメディア制約
アプリケーション状態はクライアント側に保持され、その変更はクライアントの責任において行う。変更はHTTPリクエストを行なってレスポンスを処理することによってのみ可能で、レスポンスに入ってない操作は不可。
次のアクションはform(ハイパーメディアコントロール)の中にある。 - ショッピングサイトの例:商品一覧からカートにPOSTする。
6つのアーキテクチャ制約
https://www.ca.com/content/dam/ca/jp/files/ebook/a-guide-to-rest-and-api-design.pdf
2019/12/01 CAテクノロジーズが買収されてリンク先がなくなっていたので、英語版の物に差し替え https://docs.broadcom.com/docs/a-guide-to-rest-and-api-design
https://www.redhat.com/ja/topics/api/what-are-application-programming-interfaces
(これはアーキテクチャ制約にカウントしない)NULL制約
制約がない状態から始める。 構築のプロセスにはコンポーネントから構築するパターンと、設計空間を作って制約を適用するパターンがある。 RESTは抑制と理解を強調する、設計空間を作って制約を適用するパターンによって構築された。
クライアント・サーバ
ブロードキャスト・イベントリスナーと違う
ステートレス
リクエストがなければ、クライアントが存在しないのと同じ。 ステートレスと言うのは、ステートが変わらないと言う意味ではないので注意が必要。 サーバーがアプリケーション状態を気にするなら専用のURIをつくり、リソース状態として管理すべき。
(RESTにおける)キャッシュ
自己記述的メッセージ制約とステートレス制約の上に成り立っている。 アプリケーションのキャッシュとは違い、RESTのキャッシュはネットワークを使わないことを目指す。 キャッシュを正しく使うことで、共有できるものとできないものを文書に残さなくても区別できるようになる。 リクエスト数が減ってサーバーの代金が減るという利点以外に、ネットワーク帯域という公共財を使わないようにするエシカルな理由もある。
統一インターフェース
アドレス可能性、表現を通したリソース操作、自己記述的メッセージ、ハイパーメディア制約の上に成り立つ。 1回のリクエストで様々な情報を返すことでレイテンシが高くなる、おしゃべりAPI問題。
階層化システム
クライアント・サーバーの間にプロキシ(コンポーネント間を仲介する)・ゲートウェイ(プロトコル間を仲介する)を追加する場合は統一されたインターフェースを持つ、 HTTPシステム中の「コンポーネント」として振る舞う。クライアントから見たときに透過的にHTTPサーバとして見えるようにする。
コード・オン・デマンド
<script>
タグのようにサーバはクライアントのコードが何をするか知らない。
WebAPIの設計戦略
- システムが持っていると良いと思う特性を書き出す
- 必要な特性と、犠牲にしてもいい特性を見極める
- 本当に必要な特性をもたらしてくれるアーキテクチャ制約を見つける
- その制約を具体化するプロトコルやその他標準を元に設計する(例えばHTTP,URI,HTML,Javascript)
- 2-4を繰り返す
EXTRA TALK
RESTの理解が正しくされていない理由についての考察がありました。
まず、以下の構図があります。
理論: Roy T.Fielding Experts: Mike Amundsen, Martin Fowler Mini Experts: @koriym audiense: われわれ
理論まで行く人が少く、audienseのなかだけでぐるぐる回っていて、本質的なものよりプラクティスの情報が氾濫している現状がある。 一方、こうした構図は世の中に受け入れられて広く普及する過程で役に立った文化でもある。 またRailsのようにマーケティング上手なRockstarの周りに集まり、それを広めるVIPがいてコミュニティで聞き耳を立てているコンシューマがいるという図式も紹介がありました。
最後に少数派を主義者として排除するのではなく、受け入れてみてくださいというお話がありました。