HATEOAS

#はじめに:HATEOAS ― もう一つの説明

このページは、JSON を使用するWikipedia の HATEOAS の項目を書き直したものです。ここでは、HTML を使用してこの概念を説明し、JSON API と比較します。Wikipedia に適したよりも意見の強い説明になっていますが、私たちの意見ではより正確です。

ハイパーメディア・アズ・ザ・エンジン・オブ・アプリケーション・ステート (HATEOAS) は、REST アプリケーションアーキテクチャの制約であり、他のネットワークアプリケーションアーキテクチャと区別するものです。

HATEOAS を使用すると、クライアントは、アプリケーションサーバーがハイパーメディアを通じて動的に情報を提供するネットワークアプリケーションと対話します。REST クライアントは、ハイパーメディアに関する一般的な理解を超えて、アプリケーションやサーバーとの対話方法についてほとんど、またはまったく事前に知識を持つ必要がありません。

これとは対照的に、今日の JSON ベースの Web クライアントは、通常、Swaggerなどのツールを介してドキュメントによって共有される固定されたインターフェースを介して対話します。

HATEOAS によって課せられた制限により、クライアントとサーバーがデカップリングされます。これにより、サーバー機能を独立して進化させることができます。

#

HTTP を実装するユーザーエージェントは、単純な URL を介して REST エンドポイントへの HTTP リクエストを行います。ユーザーエージェントが行う可能性のある後続のすべてのリクエストは、各リクエストへのハイパーメディアレスポンス内で検出されます。これらの表現に使用されるメディアタイプと、それらが含む可能性のあるリンクリレーションは標準化されています。クライアントは、ハイパーメディア表現内のリンクを選択するか、メディアタイプによって提供される他の方法で表現を操作することにより、アプリケーションの状態を遷移します。

このように、RESTful な相互作用は、帯域外情報ではなく、ハイパーメディアによって駆動されます。

具体的な例でこれを明確にしましょう。Web ブラウザによって発行されたこの GET リクエストを考えてみましょう。これは銀行口座のリソースを取得します。

GET /accounts/12345 HTTP/1.1
Host: bank.example.com

サーバーは、HTML を使用するハイパーメディア表現で応答します。

HTTP/1.1 200 OK

<html>
  <body>
    <div>Account number: 12345</div>
    <div>Balance: $100.00 USD</div>
    <div>Links:
        <a href="/accounts/12345/deposits">deposits</a>
        <a href="/accounts/12345/withdrawals">withdrawals</a>
        <a href="/accounts/12345/transfers">transfers</a>
        <a href="/accounts/12345/close-requests">close-requests</a>
    </div>
  <body>
</html>

この応答には、次のフォローアップアクションが含まれています。預け入れ、引き出し、振込を入力するための UI に移動するか、またはクローズリクエスト(口座を閉鎖する)に移動します。

口座がオーバードラフトになった後の時点での状況を考えてみましょう。この口座の状態の変化により、異なるリンクセットが利用可能になります。

HTTP/1.1 200 OK

<html>
  <body>
    <div>Account number: 12345</div>
    <div>Balance: -$50.00 USD</div>
    <div>Links:
        <a href="/accounts/12345/deposits">deposits</a>
    </div>
  <body>
</html>

利用可能なリンクは 1 つだけです。より多くの資金を預けるためです。口座の現在のオーバードラフト状態では、他のアクションは利用できません。この事実は、ハイパーメディア内部に反映されています。Web ブラウザは、オーバードラフト口座の概念、あるいは実際には口座自体が何であるかについて知りません。単にユーザーにハイパーメディア表現を表示する方法を知っているだけです。

したがって、ハイパーメディアがアプリケーションステートのエンジンであるという概念があります。可能なアクションは、リソースの状態が変化するにつれて変化し、この情報はハイパーメディアにエンコードされます。

上記の HTML 応答を、代わりにステータスフィールドを持つ口座の表現を返す一般的な JSON API と比較してみましょう。

HTTP/1.1 200 OK

{
    "account": {
        "account_number": 12345,
        "balance": {
            "currency": "usd",
            "value": -50.00
        },
        "status": "overdrawn"
    }
}

ここで、クライアントは `status` フィールドの値の意味、ユーザーインターフェースのレンダリングにどのように影響するか、そしてそれを使用してどのようなアクションを実行できるかを具体的に知る必要があります。クライアントは、これらのリソースの操作に使用する URL も知っている必要があります。なぜなら、それらは応答にエンコードされていないからです。これは通常、JSON API のドキュメントを参照することで実現されます。

この帯域外情報の要件は、この JSON API を HATEOAS を実装する RESTful API と区別するものです。

これは、2 つの方法間の根本的な違いを示しています。RESTful な HATEOAS HTML 表現では、すべての操作が応答に直接エンコードされます。JSON API の例では、リモートリソースを処理および操作するには帯域外情報が必要です。

#起源

HATEOAS 制約は、Roy Fielding の“統一インターフェース”機能の不可欠な部分であり、彼の博士論文で定義されています。Fielding の論文は、当時の HTML と HTTP を中心とした初期の Web アーキテクチャに関する議論でした。

Fielding は、この概念とハイパーメディアの重要な要件について、彼のブログでさらに説明しています

#HATEOAS と JSON

注:このセクションの中立的なトーンは議論されています。

2000 年代初頭、REST の概念は、初期の Web の説明としての初期の概念環境から Web 開発の他の領域に転用されました。最初に XML API 開発(多くの場合、SOAP を使用)、次に JSON API 開発です。これは、XML と JSON のどちらも HTML と同じ方法で自然なハイパーメディアではなかったという事実にもかかわらずです。

これらの新しい領域で REST への異なるレベルの準拠を特徴付けるために、リチャードソン成熟度モデルが提案され、さまざまなレベルの API の「成熟度」で構成され、最高レベルのレベル 3 は「ハイパーメディアコントロール」で構成されています。

JSON は自然なハイパーメディアではないため、ハイパーメディアの概念は上に強制的に適用するしかありません。リチャードソン成熟度モデルのレベル 3 を満たそうとする JSON エンジニアは、上記の銀行口座の例に対応する次の JSON を返す可能性があります。

HTTP/1.1 200 OK

{
    "account": {
        "account_number": 12345,
        "balance": {
            "currency": "usd",
            "value": 100.00
        },
        "links": {
            "deposits": "/accounts/12345/deposits",
            "withdrawals": "/accounts/12345/withdrawals",
            "transfers": "/accounts/12345/transfers",
            "close-requests": "/accounts/12345/close-requests"
        }
    }
}

ここで、「ハイパーメディアコントロール」は、口座オブジェクトの `links` プロパティにエンコードされています。

残念ながら、この API のクライアントはまだかなりの追加情報を知る必要があります。

上記の JSON を、ユーザーが最初の HTML 例で見つかった `/accounts/12345/deposits` へのリンクをクリックした後にブラウザによって取得された次の HTTP 応答と比較します。

HTTP/1.1 200 OK

<html>
  <body>
    <form method="post" action="/accounts/12345/deposits">
        <input name="amount" type="number" />
        <button>Submit</button>
    </form>
  <body>
</html>

この HTML 応答は、`method` 属性と `action` 属性を持つ `form` と、リソースを正しく更新するために必要な入力を提供することにより、口座残高を更新するために必要なすべての情報をエンコードしていることに注意してください。

JSON 表現は、HTML 表現と同じ自己完結型の「統一インターフェース」を持っていません。

RESTful な概念からどれだけ離れていても、JSON API を「REST」とラベル付けすることは、Roy Fielding に言わせると

HTTP ベースのインターフェースを REST API と呼ぶ人の数にうんざりしています。今日の例は SocialSite REST API です。それは RPC です。RPC と叫んでいます。表示されているカップリングが多すぎるため、X レйтингを与える必要があります。

JSON API により複雑なハイパーメディアコントロールを課す試みがなされてきましたが、一般的に業界は、HATEOAS と RESTful アーキテクチャの他の要素を放棄するより単純な RPC スタイルの API を支持してこのアプローチを拒否しています。

この事実は、HTML などの自然なハイパーメディアが RESTful システムを構築するための実際的な必要性であるという主張の強力な証拠です。

</>