LoginSignup
34
20

More than 3 years have passed since last update.

この記事は弁護士ドットコムアドベントカレンダー 20日目の記事です。
昨日の記事は@amashigeseijiさんのタスクベースUIとCQRSでした。

はじめに

@amashigeseijiさんが上記記事投稿後、以下のようなつぶやきをしていました。

本記事では@amashigeseijiさんに変わり、上記の「ハイパーメディアコントロールじゃないの?」という点について簡単に解説していきます。
ですので、上記を先に読んであることを前提にしている部分も多少あります。面白いので先に読んでからが良いと思います。

Task-Based UI

以下はCQRS Documents by Greg YoungのFigure7を引用したTask-Based UIの例です。
テーブルの各行は Inventory Item というものを表しており、 それぞれNameSupplierActive という情報を持っており、 Active の列にチェックマークが入っている Inventory Item に関しては、4列目にDeactivate というLinkを持っています。

スクリーンショット 2020-12-19 12.06.23.png

ユーザがあるInventory ItemDeactivate Linkをたどると、以下のような画面に遷移します。

スクリーンショット 2020-12-19 12.06.30.png

ユーザは、アイテムを無効にする理由についてのコメントを求められます。

原文にもありますが、この一連の操作において、ユーザの意図は非常に明確であることがわかり、ソフトウェアの誘導によって実現されています。

このソフトウェアによる誘導が、Webの世界ではハイパーメディアコントロールと呼ばれるもので、RESTにおいて非常に重要な要素1です。

ハイパーメディアコントロール

ハイパーメディアコントロールとは、アプリケーション状態(クライアントとサーバーのやりとりでクライアントがどこに位置しているかという状態)をハイパーメディアによって制御することを表します。クライアントの位置は、リクエストのURLによって表されます。サーバーはリンクによってクライアントが次に行うべき行動を示し、クライアントはそのリンクによって状態遷移を行います。

先のInventory Itemを例にしてみましょう。
アプリケーション状態の遷移図(Application state diagram;ASD)を以下に示します2。四角が状態、矢印が遷移を表します。
ASD上のFigure7Figure8は引用した画像に対応しています。

スクリーンショット 2020-12-19 17.11.29.png

ASDで表現したアプリケーションがWeb上に存在することを考えてみます。
ユーザがブラウザにFigure7を指すURLを入力します。すると、サーバーからは以下のようなページが返されます。

スクリーンショット 2020-12-19 12.06.23.png

この状態からユーザができることは、サーバーから示されたDeactivateのリンクをたどることです。
ユーザがDeactivateのリンクをクリックすると、以下のページが返されます。

スクリーンショット 2020-12-19 12.06.30.png

サーバーから示されたリンクをクリックすることで、アプリケーション状態がFigure7からFigure8に遷移しました。ハイパーメディアコントロールによるものです🎉

Figure8の状態からユーザができることは以下の2点です。

  1. CancelをクリックしてFigure7の状態に遷移する
  2. コメントを入力し、Deactivateをクリックして次の状態に遷移する

ASDでは、2の遷移先をFigure7にしていますが、いずれにせよ遷移先はサーバーによって示されているという点がポイントです。
また、2の遷移によってサーバー上のリソース状態も変化しているでしょう。
具体的にどういった変化があったのかはユーザにはわかりませんが、最初にアクセスしたFigure7の状態と2の後のFigure7の状態は異なるのではないでしょうか。

APIとして提供する

上記の体験をAPIで提供するにはどうしたら良いでしょうか。
サーバーからリンクやフォームを渡し、ユーザはそれに従って状態遷移をするという基本的な考え方は変わりません。

application/jsonがAPIのレスポンス形式としては一般的ですが、application/jsonはメディアタイプとしてハイパーメディアをサポートしていないので、クライアントはどこにURLが存在するのかわかりません。
application/hal+json3application/vnd.siren+json4などを利用するのが良いでしょう。

以下のような記事もあります。
JSONでフォームを表現する
ハイパーメディアをサポートしているフレームワークもたくさんあります。

Gregさんの考えの変化

タスクベースUIとCQRSにも注記があるとおり、
REST=CRUDと理解していたのか2009年ごろはかなりRESTに批判的でした。当時のツイートを一部引用します。

しかし、翌年にはRESTはCQRSだ(超意訳)とtweetしており、REST=CRUDという考えではなくなったように感じます。

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


  1. 4つのインターフェース制約の内の1つハイパーメディア制約になります。Hypermedia as the Engine of Application State (HATEOAS) 

  2. https://github.com/koriym/app-state-diagramALPS から生成しました 

  3. http://stateless.co/hal_specification.html 

  4. https://github.com/kevinswiber/siren 

  5. A resource-oriented application framework 

34
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
20