REST HATEOAS(成熟度レベル3)はどの程度有用/重要ですか?


110

私は、REST APIがHATEOASに準拠し、すべてのリチャードソンの成熟度レベル(http://martinfowler.com/articles/richardsonMaturityModel.html)を実装する必要があると考える一部の上級チームメンバーが信じているプロジェクトに参加しています!

AFAIKのほとんどのREST実装はHATEOASに準拠していないため、より多くの人がそれを行わないのには十分な理由があるはずです。追加された複雑さ、フレームワークの欠如(サーバー側とクライアント側)、パフォーマンスの懸念などの理由を考えることができます...

どう思いますか?現実世界のプロジェクトでHATEOASの経験はありますか?


ここでは、件名に良い記事です:medium.com/@andreasreiser94/...は基本的に、道「REST」が正常に実装されている、それはRPCです...
masterxilo

回答:


213

RESTコミュニティの誰もが、RESTは簡単だと言っています。HATEOASは、RESTアーキテクチャに困難を加える側面の1つにすぎません。

人々はあなたが提案するすべての理由のためにHATEOASをしません:それは難しいです。これにより、サーバー側とクライアントの両方が複雑になります(実際にそれを利用したい場合)。

しかし、今日、何十億もの人々がRESTのメリットを体験しています。Amazonの「チェックアウト」URLを知っていますか?私はしません。それでも、私は毎日チェックアウトできます。そのURLは変更されましたか?私は知らない、私は気にしない。

気にしてますか?画面を書いた人なら誰でも、Amazonの自動クライアントをこすり落としました。Webトラフィックを手際よく探知したり、HTMLページを読んだりして、いつどのペイロードでどのリンクを呼び出すかを見つける人。

また、Amazonが内部プロセスとURL構造を変更するとすぐに、ハードコードされたクライアントは失敗しました。リンクが壊れたためです。

それでも、カジュアルなWebサーファーはほとんど問題なく1日中買い物をすることができました。

これはRESTの動作です。テキストベースのインターフェースを解釈および直感し、ショッピングカートで小さなグラフィックを認識し、それが実際に何を意味するかを理解できる人間によって拡張されています。

ソフトウェアを書いているほとんどの人はそれをしません。自動クライアントを作成しているほとんどの人は気にしません。ほとんどの人は、最初に壊れないようにアプリケーションを設計するよりも、壊れたときにクライアントを修正する方が簡単だと感じています。ほとんどの人はそれが重要な場所に十分なクライアントを持っていません。

トラフィックの両側で専門のテクニカルサポートとITを備えた2つのシステム間で通信する内部APIを作成していて、変更を迅速かつ確実に、変更のスケジュールで通信できる場合、RESTは何も購入しません。あなたはそれを必要としません、あなたのアプリは十分に大きくありません、そしてそれは問題になるほど十分に長く生きていません。

大きなユーザーベースを持つ大規模なサイトには、この問題があります。彼らは、システムとやり取りするときに、気まぐれでクライアントコードを変更するように人々に要求することはできません。サーバーの開発スケジュールは、クライアントの開発スケジュールと同じではありません。APIの突然の変更は、関係するすべての人に受け入れられません。両側でトラフィックと操作が中断されるためです。

したがって、このような操作はHATEOASの恩恵を受ける可能性が非常に高くなります。バージョン管理が簡単で、古いクライアントの移行が簡単で、下位互換性がない場合よりも簡単です。

ワークフローの多くをサーバーに委任し、その結果に基づいて動作するクライアントは、サーバーの変更に対して、そうでないクライアントよりもはるかに堅牢です。

しかし、ほとんどの人はそのような柔軟性を必要としません。彼らは2つまたは3つの部門用のサーバーコードを作成しています。壊れた場合は修正し、通常の操作に組み込んだ。

RESTであろうとなかろうと、柔軟性は複雑さを生みます。シンプルかつ高速にしたい場合は、柔軟にせずに、「やるだけ」で完了です。システムに抽象化と逆参照を追加すると、テストが難しくなり、ボイラープレートが増え、テストするコードが増えます。

RESTの多くは、「それを必要としない」という箇条書きに失敗しています。もちろん、そうするまでは。

必要な場合は、それを使用し、レイアウトされているとおりに使用してください。RESTは、HTTPを介してデータをやり取りしません。それは今までになかった、それよりもはるかに高いレベルです。

ただし、RESTが必要で、RESTを使用する場合は、HATEOASが必要です。これはパッケージの一部であり、それが機能するための鍵となります。


11
私はあなたがこの答えに対して少なくとも1000以上のいいねを持っているべきだと感じています。正直なところ、私は次のことを想像しなければなりません。「本当の」REST質問であることがどれほど重要であるかがかなり出てきます。地獄、私がこのスレッドを見つけたとき、私は弾薬が次の会議で使用するその理由のためにいくつかグーグルをしていました。
nograde 2014

2
神(またはコード)に感謝します。誰かがHATEOASの欠点についても話しています!
IlliakaillI 2016

6
URLを簡単に変更できるという他の利点はありますか?人間とは異なり、プログラムは新しいものを処理できないため、新しいオプションを追加することはできません。さらに、知っているURLを作成することから、アクションの名前を知ることだけにシフトしました。
ジミーT.

APIコンシューマーが何も知らない場合、ユーザーアクションを1:1に委任することしかできません
Jimmy T.

2
URLの変更については、クライアントがキャッシュを使用する可能性があることを忘れないでください。そのため、サーバーで動作を維持して、以前のURLも処理する(またはリダイレクトする)必要があります。APIを進化させるための戦略として、古い動作を機能させ続ける必要があります。HATEOASはあまり役に立ちません。
ブルーノコスタ

21

はい、APIでハイパーメディアを使用した経験があります。ここにいくつかの利点があります:

  1. 探索可能なAPI:些細なことに聞こえるかもしれませんが、探索可能なAPIのパワーを過小評価しないでください。データを参照する機能により、クライアント開発者は、APIとそのデータ構造のメンタルモデルを簡単に構築できます。

  2. インラインドキュメント:リンク関係としてURLを使用すると、クライアント開発者がドキュメントを参照できるようになります。

  3. 単純なクライアントロジック:URL自体を構築するのではなく、単にURLに従うクライアントは、実装と保守が簡単です。

  4. サーバーはURL構造の所有権を取得します。ハイパーメディアを使用すると、サーバーが使用するURL構造に関するクライアントのハードコードされた知識が削除されます。

  5. コンテンツを他のサービスにオフロードする:ハイパーメディアは、コンテンツを他のサーバー(CDNなど)にオフロードするときに必要です。

  6. リンクを使用したバージョン管理:ハイパーメディアは、APIのバージョン管理に役立ちます。

  7. 同じサービス/ APIの複数の実装:同じサービス/ APIの複数の実装が存在する場合、ハイパーメディアは必要です。サービスは、たとえば、投稿やコメントを追加するためのリソースを備えたブログAPIにすることができます。ハードコードされたURLではなく、リンク関係の観点からサービスが指定されている場合、同じサービスが異なるURLで複数回インスタンス化され、異なる会社によってホストされていても、1つの単一のクライアントによって同じ明確に定義されたリンクのセットを通じてアクセスできます。

これらの箇条書きの詳細な説明は、次の場所にあります。http//soabits.blogspot.no/2013/12/selling-benefits-of-hypermedia.html

(ここに同様の質問があります:https : //softwareengineering.stackexchange.com/questions/149124/what-is-the-benefit-of-hypermedia-hateoasここで私は同じ説明をしました)


同じサービスの複数の実装:詳しく説明できますか?それがどのように役立つかわかりません。
アバドン2018

私はそれをテキストで説明しようとしました。それは役に立ちますか?
ジョーンWildt

11

リチャードソンの成熟度レベル3は価値があり、採用する必要があります。JørnWildtはすでにいくつかの利点を要約しており、Wiltによる他の回答はそれを非常によく補完しています。

ただし、リチャードソンの成熟度レベル3は、フィールディングのHATEOASと同じではありません。Richardsonの成熟度レベル3は、API設計のみに関するものです。FieldingのHATEOASもAPIの設計に関するものですが、クライアントソフトウェアにはは、リソースがメディアタイプで定義されている構造を超えた特定の構造を持っていると想定してはならないこと。これには、特定のWebサイトに関する知識を持たないWebブラウザーなどの非常に一般的なクライアントが必要です。Roy FieldingはRESTという用語を作成し、HATEOASをRESTへのコンプライアンスの要件として設定しているので、問題はHATEOASを採用したいのですか、それともAPIをRESTfulと呼べるかどうかです。できると思います。説明させてください。

HATEOASを達成したとします。現在、アプリケーションのクライアント側は非常に一般的ですが、リソースのセマンティクスについての知識がないと、リソースのプレゼンテーションをそれらのセマンティクスを反映するように調整できないため、ユーザーエクスペリエンスが悪い可能性があります。リソース「car」とリソース「house」のメディアタイプが同じ場合(例:application / json)、プロパティ(名前/値のペア)のテーブルなど、同じ方法でユーザーに表示されます。

しかし、わかりました、私たちのAPIは本当にRESTfulです。

ここで、このAPIの上に2番目のクライアントアプリケーションを構築するとします。この2番目のクライアントはHATEOASのアイデアに違反しており、リソースに関する情報をハードコーディングしています。車と家を異なる方法で表示します。

APIは引き続きRESTfulと呼ばれますか?私はそう思う。クライアントの1つがHATEOASに違反したのは、APIのせいではありません。

私はRESTfulなAPIを、すなわちAPIの一般的なクライアントを実装することができるために構築するために助言する理論的には、ほとんどの場合、あなたが必要とするいくつかのユーザビリティの要件を満たすためにあなたのクライアントでのリソースに関するハードコードされた情報を。それでも、クライアントとサーバー間の依存関係を減らすために、可能な限りハードコードしないようにしてください。

私はと呼ばれる私のREST実装パターンのHATEOASのセクションが含まれているJARESTを


8

応答がHAL-JsonであるRESTレベル3 APIを構築しています。HATEOASは、フロントエンドとバックエンドの両方に最適ですが、課題が伴います。HAL-Json応答内でACLを管理するために、いくつかのカスタマイズ/追加を行いました(HAL-Json標準に違反しません)。

私が見るHATEOASの最大の利点は、フロントエンドアプリケーションでURLを記述/推測する必要がないことです。必要なのはエントリポイント(https://hostname)だけで、そこから、応答内に提供されているリンクまたはテンプレート化されたリンクを使用して、リソースを簡単に参照できます。そのように、バージョニングは簡単に処理でき、URLの名前変更/置換、フロントエンドコードを壊すことなくリソースを追加の関係で拡張できます。

フロントエンドでのリソースのキャッシングは、セルフリンクを使用した簡単な作業です。リソースもソケット接続を介してクライアントにプッシュします。リソースもHALでレンダリングされるため、同じ方法で簡単に追加してキャッシュできます。

HAL-Jsonを使用するもう1つの利点は、文書化された標準に従う必要があるため、応答モデルがどのように見えるかが明確であることです。

私たちのカスタマイズの一つは、我々は行動が自己リンクオブジェクト内のオブジェクト追加したことである認証されたユーザーが、それぞれのリソースで実行することが許可されているアクションまたはCRUD操作フロントエンドに露出します(create:POSTread:GETupdate:PUTedit:PATCHdelete:DELETE)。このように、フロントエンドACLはREST API応答によって完全に指示され、この責任は完全にバックエンドモデルに移されます。

簡単な例を挙げれば、次のようなHAL-Jsonの投稿オブジェクトを作成できます。

{
    "_links": {
        "self": {
            "href": "https://hostname/api/v1/posts/1",
            "actions": {
                "read": "GET",
                "update": "PUT",
                "delete": "DELETE"
            }
        }
    },
    "_embedded": {
        "owner": {
            "id": 1,
            "name": "John Doe",
            "email": "john.doe@example.com",
            "_links": {
                "self": {
                    "href": "https://hostname/api/v1/users/1",
                    "actions": {
                        "read": "GET"
                    }
                }
            }
        }
    },
    "subject": "Post subject",
    "body": "Post message body"
}

これで、フロントエンドで実行する必要があるのは、実行するアクションがアクションオブジェクト内にあるかどうかをチェックAclServiceするisAllowedメソッドを使用してを作成することだけです。

現在、フロントエンドでは、次のようにシンプルに見えます。 post.isAllowed('delete');

RESTレベル3はすばらしいと思いますが、いくつかの問題が発生する可能性があります。RESTについて十分に理解している必要があります。レベル3のRESTを使用する場合は、RESTのコンセプトに厳密に従うことをお勧めします。そうしないと、RESTを実装するときに簡単に道に迷ってしまいます。

私たちの場合、フロントエンドとバックエンドの両方を構築しているという利点がありますが、原則として違いはありません。しかし、私がチームで見た一般的な落とし穴は、一部の開発者がフロントエンドのニーズに「適合する」ようにバックエンドモデルを変更することによってフロントエンドの問題(アーキテクチャ)を解決しようとすることです。


1
とても良い答えです。そのような実用的な例は、元の質問者が探していたものだと思います。
www.admiraalit.nl

2

私は実際のプロジェクトでHATEOASを使用しましたが、Richardsonとは解釈が異なります。それがあなたの上司が望むものであれば、私はあなたがそれをやるべきだと思います。HATEOASは、GET以外の動詞の機能を公開するために、リソースにHTML Doctype、関連リソースへのハイパーリンク、およびHTMLフォームを含める必要があることを意味します。(これは、Acceptタイプがtext / htmlである場合です。他のコンテンツタイプはこれらの追加機能を必要としません。)アプリケーション全体のすべてのRESTリソースを結合する必要があるという信念がどこからもたらされたのかはわかりません。ネットワークアプリケーションには、直接関連する場合と直接関連しない場合がある複数のリソースが含まれている必要があります。または、XML、JSON、およびその他のタイプがこれに従う必要があると考えられている理由。(HATEOASはHTML固有です。)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.