この記事は弁護士ドットコムアドベントカレンダー 20日目の記事です。
昨日の記事は@amashigeseijiさんのタスクベースUIとCQRSでした。
はじめに
@amashigeseijiさんが上記記事投稿後、以下のようなつぶやきをしていました。
タスクベースUIってハイパーメディアコントロールじゃないの?とかの話題もあるけど、時間かけなきゃ書けない...
— 天重誠二 (@tenjuu99) December 18, 2020
本記事では@amashigeseijiさんに変わり、上記の「ハイパーメディアコントロールじゃないの?」という点について簡単に解説していきます。
ですので、上記を先に読んであることを前提にしている部分も多少あります。面白いので先に読んでからが良いと思います。
Task-Based UI
以下はCQRS Documents by Greg YoungのFigure7を引用したTask-Based UIの例です。
テーブルの各行は Inventory Item
というものを表しており、 それぞれName
、Supplier
、Active
という情報を持っており、 Active
の列にチェックマークが入っている Inventory Item
に関しては、4列目にDeactivate
というLinkを持っています。
ユーザがあるInventory Item
のDeactivate
Linkをたどると、以下のような画面に遷移します。
ユーザは、アイテムを無効にする理由についてのコメントを求められます。
原文にもありますが、この一連の操作において、ユーザの意図は非常に明確であることがわかり、ソフトウェアの誘導によって実現されています。
このソフトウェアによる誘導が、Webの世界ではハイパーメディアコントロールと呼ばれるもので、RESTにおいて非常に重要な要素1です。
ハイパーメディアコントロール
ハイパーメディアコントロールとは、アプリケーション状態(クライアントとサーバーのやりとりでクライアントがどこに位置しているかという状態)をハイパーメディアによって制御することを表します。クライアントの位置は、リクエストのURLによって表されます。サーバーはリンクによってクライアントが次に行うべき行動を示し、クライアントはそのリンクによって状態遷移を行います。
先のInventory Item
を例にしてみましょう。
アプリケーション状態の遷移図(Application state diagram;ASD)を以下に示します2。四角が状態、矢印が遷移を表します。
ASD上のFigure7
、Figure8
は引用した画像に対応しています。
ASDで表現したアプリケーションがWeb上に存在することを考えてみます。
ユーザがブラウザにFigure7
を指すURLを入力します。すると、サーバーからは以下のようなページが返されます。
この状態からユーザができることは、サーバーから示されたDeactivate
のリンクをたどることです。
ユーザがDeactivate
のリンクをクリックすると、以下のページが返されます。
サーバーから示されたリンクをクリックすることで、アプリケーション状態がFigure7
からFigure8
に遷移しました。ハイパーメディアコントロールによるものです🎉
Figure8
の状態からユーザができることは以下の2点です。
-
Cancel
をクリックしてFigure7
の状態に遷移する - コメントを入力し、
Deactivate
をクリックして次の状態に遷移する
ASDでは、2の遷移先をFigure7
にしていますが、いずれにせよ遷移先はサーバーによって示されているという点がポイントです。
また、2の遷移によってサーバー上のリソース状態も変化しているでしょう。
具体的にどういった変化があったのかはユーザにはわかりませんが、最初にアクセスしたFigure7
の状態と2の後のFigure7
の状態は異なるのではないでしょうか。
APIとして提供する
上記の体験をAPIで提供するにはどうしたら良いでしょうか。
サーバーからリンクやフォームを渡し、ユーザはそれに従って状態遷移をするという基本的な考え方は変わりません。
application/json
がAPIのレスポンス形式としては一般的ですが、application/json
はメディアタイプとしてハイパーメディアをサポートしていないので、クライアントはどこにURLが存在するのかわかりません。
application/hal+json
3やapplication/vnd.siren+json
4などを利用するのが良いでしょう。
以下のような記事もあります。
JSONでフォームを表現する
ハイパーメディアをサポートしているフレームワークもたくさんあります。
Gregさんの考えの変化
タスクベースUIとCQRSにも注記があるとおり、
REST=CRUDと理解していたのか2009年ごろはかなりRESTに批判的でした。当時のツイートを一部引用します。
watching the REST group discuss CQS is extremely painful.
— Greg Young (@gregyoung) May 26, 2009
しかし、翌年にはRESTはCQRSだ(超意訳)とtweetしており、REST=CRUDという考えではなくなったように感じます。
I used to think RESTand a CQRS based architecture were at odds with each other. This is not true, REST done right is a `CQRS` architecture
— Greg Young (@gregyoung) May 15, 2010
DDDとALPS
うっかりDDDを持ち出しました。朝5時とかにならないよにさらっと書きます。
@amashigeseijiさんの記事にもあるとおり、DDDがタスクベースUIを必要とするのは、操作の意味づけのためです。
ALPSを用いることによって、APIがクライアントに対してセマンティックをシェアできるようになります。
APIレスポンスの内容だけでなく遷移に対してセマンティックを付与することも可能です。
弁護士ドットコムアドベントカレンダー 10日目の@koriymさんの記事が詳しいです。
メディアタイプとALPSプロファイル
まとめ
CQRS Documents by Greg YoungのTask-Based UIを例に、ハイパーメディアコントロールについて解説しました。
ハイパーメディアコントロールそのものは、特に目新しいものではなかったと思います。普段当たり前のように体験しているものですからね。
ですが、APIになったとたんハイパーメディアコントロールは失われてしまいがちです。
APIを設計する際にも状態遷移を中心に考え、サーバーからリンクやフォームを示しクライアントの状態遷移を制御することによって、Web本来の拡張性の高いAPIをデザインできるのではないでしょうか。
RESTful Web APIsという本の読書会を弁護士ドットコム主催で2019年10月から開催しています。
BEAR.Sundayの作者である@koriymさん、RESTエキスパートの@tkawaさんご協力のもと、現在はオンラインで月1回のペースで開催しています。
年明け1月は、総集編になります。RESTについて理解を深めたい方はぜひご参加ください。
日程は現在調整中ですが、私のツイッターで日程決まり次第アナウンスします。https://twitter.com/TSUCHIYA_Naoki
明日は、@komtakiさんの「狼少年にならないフロントエンドエラー監視システムの工夫」です。お楽しみに!
参考文献
Richardson, Leonard; Amundsen, Mike; Ruby, Sam. RESTful Web APIs: Services for a Changing World . O'Reilly Media. Kindle 版.
https://magazine.rubyist.net/articles/0050/0050-Hypermedia.html
https://docs.microsoft.com/en-us/previous-versions/ms997506(v=msdn.10)
https://www.slideshare.net/tkawa1/truerest20191214
https://speakerdeck.com/koriym/rest-6-plus-4falsezhi-yue
-
4つのインターフェース制約の内の1つハイパーメディア制約になります。Hypermedia as the Engine of Application State (HATEOAS) ↩
-
https://github.com/koriym/app-state-diagram で ALPS から生成しました ↩
-
A resource-oriented application framework ↩