物事をシンプルに保ち、名前の衝突を避けるために、私はレコード リソース内のリンクを次のようにまとめています...
{
id: 211,
first_name: 'John',
last_name: 'Lock',
_links: [
{ rel: 'self', href: 'htttp://example.com/people/211' }
]
}
しかし、コレクションにリンクを実装する方法がわかりません。私は長い時間をかけてWebを巡り、例を探しましたが、それほどシンプルでないハル私は自分の問題を解決することができません。
[
{id:1,first_name:.....},
{id:2,first_name:.....},
{id:3,first_name:.....},
"_links": "Cant put a key value pair here because its an-array"
]
つまり、配列をコンテナ オブジェクトにラップする必要があります。
{
people: [ {id:1,first_name:.....} ],
links: [ { rel:parent, href:.... ]
}
しかし、これは単一のリソースとは異なるため、レコードをコレクションのように動作させ、コンテナーにラップすることにします。
{
person: {
id: 211,
first_name: 'John',
last_name: 'Lock'
},
links:[
{ rel: 'self', href: 'htttp://example.com/people/211' }
]
}
表面的には、これは非常に優れたソリューションのように見えます。結果の JSON は 1 レベル深くなりますが、HATEOAS が実装されているので、これですべて良いのではないでしょうか。しかし、そうではありません。本当の問題は、コレクションに戻ったときに発生します。単一のリソースがコレクションとの一貫性を保つためにコンテナーにラップされたので、変更を反映するためにコレクションを変更する必要があります。そして、ここから状況が悪化します。非常に悪化します。コレクションは次のようになります...
{
"people": [
{
"person": {
....
},
"links" : [
{
"rel": "self",
"href": "http://example.com/people/1"
}
]
},
{
"person": {
....
},
"links" : [
{
"rel": "self",
"href": "http://example.com/people/2"
}
]
}
],
"links" : [
{
"rel": "self",
"href": "http://example.com/people"
}
]
}
コレクションに HATEOAS を実装するより簡単な解決策はありますか? それとも、データ構造を過度に複雑にすることを余儀なくされた HATEOAS とはお別れすべきでしょうか?
ベストアンサー1
見た目が少し肥大化しているという理由だけで、HAL をすぐに却下しないでください (JSON 形式では、非常に最小限です)。
HAL と JSON の関係は、HTML とプレーンテキストの関係と同じです。
ハイパーリンクを追加します。REST にはハイパーリンクと、一般的に理解されている表現形式 (HAL や Collection+JSON など) が必要です。REST には HATEOAS も必要です。HATEOAS がなければ REST ではありません。もちろん、HATEOAS にはハイパーリンクが必要です。
あなたの場合、コレクションリソースを構築しようとしています。IANAに登録された関係これは「アイテム」(逆の関係は「コレクション」)です。以下は、HAL での People コレクションの表現です。
{
"_links": {
"self": { "href": "http://example.com/people" },
"item": [
{ "href": "http://example.com/people/1", "title": "John Smith" },
{ "href": "http://example.com/people/2", "title": "Jane Smith" }
]
},
"_embedded": {
"http://example.com/rels#person": [
{
"first_name": "John",
"last_name": "Smith",
"_links": {
"self": { "href": "http://example.com/people/1" },
"http://example.com/rels#spouse": { "href": "http://example.com/people/2" }
}
},
{
"first_name": "Jane",
"last_name": "Smith",
"_links": {
"self": { "href": "http://example.com/people/2" },
"http://example.com/rels#spouse": { "href": "http://example.com/people/1" }
}
}
]
}
}
注記:
このコレクションの主なデータは から取得されます
_links.item[]
。これらはコレクション内の項目です。各項目の完全な (または少なくとも一部の追加) データは配列で使用できます。クライアントがこれらの追加データを必要とする場合は、各 を_embedded
検索して見つける必要があります。これは HAL の設計上の制約です。他のハイパーメディア表現形式にも同様の制約があります (ただし、方向は逆になる場合があります)。_embedded[n]._links.self.href
n
title
配列の各メンバーに値を追加しましたitem
。これは、HTML にレンダリングする場合は開始アンカー タグと終了アンカー タグの間に表示できます。また、クライアントで表現をさらに処理する必要なく、クライアントのメニュー項目のテキストとして表示できます。ID パラメータはありません。他のリソースへのすべての参照はハイパーリンクとして公開されます。クライアントは、事前に定義された場所で URL に ID を貼り付けて URL を「構築」する必要はありません。これは帯域外情報となり、クライアントとサーバーへの独立した変更を妨げます。
相対 URL は問題を引き起こす可能性があるため、すべてのハイパーリンクは絶対である必要があります。すべての関係は、IANA ページにリストされているか、URI を使用して定義する必要があります。理想的には、その URI は、もう一方の端にある関係に関するドキュメントを含む、逆参照可能な HTTP URL である必要があります。