Software engineering from east direction

六本木一丁目で働くソフトウェアエンジニアのブログ

REST についての koriym さん開催のトークイベント 「Final Object #0」 トーク内容まとめ(参加レポート) #FinalObject

@koriym さんによって主催された、Final Objectというトークイベントに参加してきました。 株式会社TRASTA が会場で開催されました。

f:id:khigashigashi:20190219192526j:plain
会場の様子

ハッシュタグは、 #FinalObject でした、Togetter でまとめておきました。

togetter.com

このイベントは、招待制で、主に @koriym さんと@kseta19さんが招待した約20名の方が参加されていました。 普段、カンファレンスやOSSで活躍されている方々ばかりでとても密度の高い場で、@koriym さんのトークをガッツリ聞くという会になりました。 タイトルにも記載していますが、今回のトークのテーマは、 REST でした。

以下、話していただいたことを速記でまとめていったものを構成し直したので、ぜひご覧ください。

イベントの趣旨

個人的なトークイベントをやってみたい意図があった。特にやりたかったのが、「話すことに主眼をおいた会」だった。
今回のイベントに、「○△□」という仙厓義梵の絵を設定した。

仙厓義梵《○△□》「わかる」がわかるか──「中山喜一朗」:アート・アーカイブ探求|美術館・アート情報 artscape

仙厓義梵でよく引用されて有名なのが、「指月布袋画賛」という絵。

blogs.yahoo.co.jp

「愚者は指を見る」と説明されるこの絵は、とても楽しそうに描かれている。このことから、「真理を求める人達が、その過程を楽しむ意味」というふうに捉えられたそう。

戻って、「○△□」という絵は、もっとも複雑な絵として説明されるが、これは、「真理へ向かっていく過程」を表しているふうに考えた。具体的には以下。

  • 「□(四角)」が拡散する問題
  • 「△(三角)」が自分なりの結論を表している
  • 「○(丸)」が真理を表している、開発者にとっての真理

これら3つの「○△□」はつながっていることから、「拡散している状態(「□」)から真理(「○」)へ近づいていく」ということを表現していると解釈した。
今回の会では、 Think, "Talk" and Code という言葉を使っている、これも「○△□」に照らし合わせて次のように考えている。

  • Think 拡散している状態で考える
  • Talk 自分なりの考えを話す
  • Code 開発者にとっての真理:コーディング

今日のテーマは「REST」。RESTについては次の記事で、ほとんどの人が理解していないと指摘されているテーマ。

blog.steveklabnik.com

マーシャル・マクルーハン の、"誰が水を発見したかは知らないが、それが魚でないことだけは確かだ" という言葉に近い状態で、このテーマを理解することは難しい状態にある。

前段:全てを結ぶ力

まず、以前のPHPカンファレンスで発表されていた「全てを結ぶ力」という内容を、RESTについて話すために話されました。 koriym.github.io koriym.github.io

Hypertext

  • Hyper Text Markup Language
  • Hypertextとは、複数のテキストを相互に関連付け、結びつける仕組み
  • Vannervar Bush(原爆を作った人)の AS WE MAY THINK
      - 人は本のように序章・次章といった風に考えない
      - 思考はそれぞれリンクされている
    
  • Ted Nelson が、HyperTextという言葉を生み出した
  • Bill Atkinson
    • HyperCard
    • HypertextをGUIシステムとして実装した
    • プログラムはテキストで書かれていない、ボタンや壁紙などの中に書かれている
      • VISUAL BASICのイメージが身近に想像できるかも

WWW 1991

REST の本編

RESTful WEB APIについて

Roy T.Fieldingによる論文によって展開された理論。

www.ics.uci.edu

RESTについての本で、RESTful Web APIs: Services for a Changing World (English Edition) の特に「Appendix C. An API Designer’s Guide to the Fielding Dissertation」が良い内容。今日の話はここについて。

f:id:khigashigashi:20190220224705j:plain
https://www.amazon.co.jp/dp/B00F5BS966/ref=cm_sw_r_tw_dp_U_x_qluBCbZ9ZK2HY

Web APIアーキテクチャスタイルがある。

APIにはいくつかのアーキテクチャスタイルがある。

www.apiacademy.co

  • Tunneling: SOAP
  • Object: CRUD
  • HyperMedia: REST
  • Query Style: GraphQL
  • Event Driven Style
    • メッセージ思考
    • URI Styleなどと違いクライアント・サーバに会話がない一方通行

今回の話で、FocusするのはHypermedia Styleである。

roy.gbiv.com

Webの特性

Webの4つの特性

  • 低い参入障壁
  • 拡張性
  • 分散ハイパーメディア
  • インターネット規模

低い参入障壁 = Easy

  • Webブラウザにマニュアルは不要
    • ex FTPならコマンド覚えないと
    • サーバー側も設置が簡単

拡張性

  • 変化し続けられる
  • 拡張性がない例 = ゲームのカセット、一度しかデプロイできない

分散ハイパーメディア

  • 表現・制御情報はリモート側にある、サーバ側でコントロール
  • 分散ハイパーメディアの原則
    • プレゼンテーション = 表現
    • 制御情報
      • リモコンは何ができるかがクライアントに決まってる。ボタンをどう押すか
      • WEBはa tagというリンクによって制御情報が含まれている。POSTしたければ何が必要かはformタグに書いてある
      • 何ができるか、表現の中に制御情報が与えられている
  • リソース間のリンク(安全な遷移)、リソース状態の変更(安全でない遷移)を受け取る。これはサーバサイドがダイナミックに変更可能
  • クライアントを壊さずにサーバの動作を変えられないのであれば拡張性がない
    • URIが変わったらクライアント側が見れない」 NG!
    • クライアントにURIをハードコーディングしてたら拡張性がない

インターネット規模

  • 大きさのことではない
  • 無秩序なスケーラビリティ
    • 全体を理解しなくてもいい。自分が新しいページを公開しても全体が壊れることはない、独立している。
  • 独立した配備

APIはWEBではない

  • 人間がいない
  • セマンテックギャップの発生

どの特性を組み合わせるか

  • 簡単な方法は、「分散ハイパーメディア」特性を捨てることだが、「拡張性」・「インターネット規模」が喪失する。
  • 低い参入障壁 + 拡張性
    • 全てのクライアントを一度に変更する必要がある
    • 社内API といったケース
  • インターネット規模 + 低い参入障壁
  • 拡張性とインターネット規模
    • 分散ハイパーメディアを使うが、低い参入障壁は失われる
  • 人間のWeb(ユーザー視点では、ブラウザで人間が普段見るWeb)では4つの重要な要件(4つの特性)を網羅されてる
    • それに対するTed Nelsonの批判
      • 片方向のリンク、Hypertextではない
      • 「アクセスしたら初めて404とわかる」
    • Web APIの場合はどれかの特性を諦めないといけない

REST(Representational State Transfer)

Architectural Styles and the Design of Network-based Software Architecturesの内容に入っていく。

  • フィールディング制約は、6つのアーキテクチャ制約と、4つのインタフェース制約から構成される。
  • 「HTTP」は標準、これは制約
  • インタフェースについての間違いを正す
    • 統一されたHTTPメソッド(GET / POST / PUT / DELETE) という意味ではない。
    • CRUD over HTTPではない
    • URIはお化粧にすぎない。

フィールディング制約を説明するに当たり、Redhatの以下の資料を引用されながら説明されました。

www.redhat.com

REST および API設計ガイド(ca technologies)

NULL制約から始まる

統一インターフェース

統インターフェースは、4つの側面を含む。

リソースの識別

  • リソースのID = URI
  • 一つのものに多くのリソースをもたせすぎているのはBad

表現によるリソース操作

  • 表現可能ななんでも
    • ペットボトル・電気・気象条件 ...etc
  • 実態がバイト列 = ネットワークで転送可能
  • GET/POSTのセットで会話していく

自己記述的メッセージ

  • 理解するための情報
    • Content-Type, Link Header, Profileへの参照
    • Cache情報、「Cacheがいつまで有効か」はクライアントではなくサーバが知っている
  • HTTPの失敗
    • HTTP 1.0 Hostヘッダーがない
      • HTTP 1.1でHostヘッダーが入った
    • HTTP 1.1 リクエストがわからない
      • BEAR.Sundayでは、HALを利用することでこの"Bug"を解消している

ハイパーメディア制約(Hypermedia As The Engine Of Application State)

  • HATEOAS
  • アプリケーション状態・リソース状態を区別すること
  • アプリケーション状態の保持・変更はクライアント
  • クライアントは、HTTPリクエスト・レスポンス処理によって、アプリケーション状態を変更できる
  • 次のアクションは表現の中のハイパーメディアコントロールにある
    • HTMLでいうとForm
    • カートに入れる、書評を書くと行った選択肢がレスポンスの中にある

6つのアーキテクチャ制約

REST および API設計ガイド(ca technologies) を主に引用して説明されました。

6つの制約

  • クライアント・サーバー
  • ステートレス
  • キャッシュ
  • 統一インターフェース
  • レイヤ化システム
  • コード・オン・デマンド(オプション)

クライアント・サーバー

  • サービスが1つ以上の処理を行い、クライアントがこのような処理を要求するまでサービスが待機することが必要
  • Photoshopは分かれてない、一人しか使えない、クライアント・サーバーの会話がない

ステートレス

  • リクエスト間は無関係。
  • Cookieは違反 - 共有キャッシュが使えない→スケーラビリティが低下

キャッシュ

  • RESTの本質は、HypertextとCache
  • Cacheはパフォーマンス・UXに直結する
  • 自己記述的メッセージ
    • 「どれだけキャッシュできるか?」という情報が記述されている
    • クライアントはCacheについて意識しない、「3秒保持する」ということはサーバ側
  • RESTにおけるキャッシュの目的は、obtained by not using the network、ネットワークを使わないこと、これが一番の目的。
  • 失敗例、サーバーサイドのみでクライアントがキャッシュしていない 。
  • max-age
    • ex. Cache-Control: max-age=3600, Vary: Accept-Language
    • Vary Headerが大事
    • 二回目はサーバにアクセスしない。ただし、アプリケーション開発者はそれを意識しない。
    • max-age・Varyの活用により、クライアントからサーバーへのリクエスト自体がなくなった
  • 条件付きリクエスト
    • ex. If-None-Match: 3, Response: Etag :3
      • id: 3じゃなければ返して
      • 304 Not Mofified の返却
    • リクエストは発生するが、Headerのみのレスポンスとなる、Bodyがない
  • ネットワーク帯域は公共財、通信量を減らすのは金額にも影響があるし、倫理的でもある
  • Public cache
    • Cache-Control: public の設定
    • publicなものなのか、privateなものなのかが大事になる
    • public/private設定により、当該リソースが「そのまま共有できるかどうか」が明確になり、品質の向上・ドキュメンテーションにつながる
  • Cache設計
  • 高いレイテンシの「おしゃべり」API = 会話しすぎなAPI

階層化システム

  • HTTPシステムの中のコンポーネント
  • 相互に意識して、middlewareのインストールが必要とかそういうのはない
  • proxy、キャッシュサーバなど中継点を追加・削除できる

コード・オン・デマンド

  • クライアントのコードが何するかわからない -> 可視性の欠如

API設計戦略

  1. 良さそうな特性を書き留める
  2. 必要なもの、犠牲にしてもいいか考える
  3. 制約のセットを見つける
  4. プロトコル。標準のセット
  5. 繰り返す

さいごに

  • Web APIはセマンティックギャップ
  • 解決策は見えていない
  • RESTは、低い参入障壁を犠牲にして、拡張性とインターネット規模をとった
    • より賢いクライアントライブラリを使って参入証跡を下げることは可能、ただし、拡張性・インターネット規模を取り戻すことはできない
  • HTTP, URL, HTML, and Javascript

参加して感想

普段のカンファレンスでは絶対に聞けないレベルのとても興味深い話が聞けてとても勉強になりました。

個人的に面白かったのが、「人間がWebを構成する中で一番賢いコンポーネントで、APIは人間がいないセマンティックギャップが発生する」 という点で、それが故に、背景・状況によって必要な特性を選択・組み合わせていく必要があるという点でした。

設計者の考え方として面白かったのは、RESTの論文が、「制約がない状態から考える」というところから、2つのアプローチをあげているところで、どういう思考プロセスで考えているんだろうかという部分が垣間見えて良いなと思いました。

#1があれば、また参加したいなと強く思った会だったと共に、次の機会があれば、また今日よりも設計について理解が深まって議論できる自分でありたいなと感じました。

@koriymさん、開催・招待いただき誠にありがとうございました!@kseta19さん、会場の準備など誠にありがとうございました!