38

物事をシンプルに保ち、名前の衝突を避けるために、私はこのようにレコード リソースにリンクをまとめています...

{
    id: 211,
    first_name: 'John',
    last_name: 'Lock',
    _links: [
        { rel: 'self', href: 'htttp://example.com/people/211' }
    ]
}

ただし、コレクションにリンクを実装する方法がわかりません。私は例を求めて Web をトロールするのに長い時間を費やしましたが、あまり無駄のないHALを使用する以外は、問題を解決できません。

[
    {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 に別れを告げるべきでしょうか?

4

4 に答える 4

39

少し肥大化したように見えるという理由だけで、HAL をすぐに閉じないでください (JSON 形式では非常に最小限です)。

HAL は JSON にとって、HTML はプレーン テキストに似ています。

ハイパーリンクを追加します。REST には、ハイパーリンクと一般的に理解されている表現形式 (HAL や Collection+JSON など) が必要です。REST には HATEOAS も必要です。HATEOAS がなければ REST ではありません。もちろん、HATEOAS にはハイパーリンクが必要です。

あなたの場合、コレクション リソースを構築しようとしています。そのためのIANA登録関係は「アイテム」(逆関係は「コレクション」)です。People コレクションの HAL での表現は次のとおりです。

{
    "_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配列で利用できます。クライアントがこれらの追加データを必要とする場合、_embedded[n]._links.self.href各を検索して見つける必要がありますn。これは HAL の設計上の制約です。他のハイパーメディア表現形式にも同様の制約があります (ただし、おそらく逆方向になります)。

  • 配列titleの各メンバーに値を追加しました。itemこれは、HTML にレンダリングする場合、またはクライアントでメニュー項目のテキストとしてレンダリングする場合は、開始アンカー タグと終了アンカー タグの間に表示できます。クライアントによる表現のさらなる処理は必要ありません。

  • ID パラメータはありません。他のリソースへのすべての参照は、ハイパーリンクとして公開されます。クライアントは、事前に定義された場所で ID を URL に貼り付けて URL を「構築」する必要はありません。これは、クライアントとサーバーへの独立した変更を禁止するアウトオブバンド情報を構成します。

  • 相対 URL は問題を引き起こす可能性があるため、ハイパーリンクはすべて絶対リンクにする必要があります。すべての関係は、その IANA ページにリストするか、URI を使用して定義する必要があります。理想的には、URI は参照解除可能な HTTP URL であり、相手側の関係に関するドキュメントが含まれている必要があります。

于 2013-08-06T14:41:21.957 に答える
15

JSON リンクはまだ解決されていないようです。いくつかの候補があります:

参考文献

于 2014-12-21T20:02:58.293 に答える
3

まず、コレクション (JSON 配列) を返すエンドポイントを持つ API が本当に RESTful であるとは思えません。ただし、ほとんどの「REST」API は、ここでルールを曲げます。

私は最近、 restbusと呼ばれるNextBus XML フィード用の REST API を開発しました。この API は、HATEOAS スタイルのハイパーテキスト リンクを使用しながら、いくつかのエンドポイントからコレクションを返します。以下は、私が使用した構造のサンプルです。

{
  // ... SF-Muni resource from restbus API ...

  _links: {
    self: {
      href: "http://localhost:3535/agencies/sf-muni",
      type: "application/json",
      rel: "self",
      rt: "agency",
      title: "Transit agency 'sf-muni'."
    },
    to: [
      {
        href: "http://localhost:3535/agencies/sf-muni/routes",
        type: "application/json",
        rel: "describedby",
        rt: "route",
        title: "A collection of routes for transit agency 'sf-muni'."
      },
      {
        href: "http://localhost:3535/agencies/sf-muni/vehicles",
        type: "application/json",
        rel: "describedby",
        rt: "vehicle",
        title: "A collection of vehicles for transit agency 'sf-muni'."
      }
    ],
    from: [
      {
        href: "http://localhost:3535/agencies",
        type: "application/json",
        rel: "bookmark",
        rt: "agency",
        title: "A collection of transit agencies. This is the API root!"
      }
    ]
  }

}

HALなどの一般的な JSONリンク戦略 (または関連するメディア タイプ) のいずれにも従お うとしません。それらはIETF Standards Trackに(まだ)含まれていないように見えるからです。代わりに、リンク オブジェクトのターゲット属性リンク関係の値は、 RFC 5988 Web リンクの仕様を可能な限り満たしています。

レストバス ハイパーテキスト リンク構造の詳細を確認できます。

于 2014-02-18T23:53:04.367 に答える