4

私は、リソースがかなり相互に関連しているRESTフルAPIを使用しています。リソースは相互に参照し、これらの参照は作成または削除される場合があります。リソースがハイパーリンクを使用して相互に参照するときに、リソースの関連付けをサポートする方法が少しわかりません。

簡単な例は、AとBの2つのリソースで続きます。

Resource A:
  name: integer
  list_b: [list of resource B]

Resource B:
  id: integer
  description: String

現在、AはドキュメントにBを含めていませんが、Bをリンクしています。ハイパーメディアを使用すると、次のようになります。

Resource A:
{
    id: 1,
    list_b: [
        { id: 1, href: "https://server/api/b/1" },
        { id: 2, href: "https://server/api/b/2" }
    ]
}

ユーザーがAのリストにあるB参照の1つを追加または削除したい場合、ハイパーリンクの存在を考慮して、どのように行うのですか?ユーザーが1回のPUT操作でAリソース全体を更新できるようにしたいのですが、出力にはBのどの値が必要かを示すものはありません。ユーザーが次のようなコンテンツでPUTを実行することは私には理にかなっています。

Resource A:
{
    id: 1,
    list_b: [
        { id: 1, href: "https://server/api/b/1" },
        { id: 2, href: "https://server/api/b/2" },
        { id: 3 },
    ]
}

次のように(応答で)更新されたリソースを受け取ります。

Resource A:
{
    id: 1,
    list_b: [
        { id: 1, href: "https://server/api/b/1" },
        { id: 2, href: "https://server/api/b/2" },
        { id: 3, href: "https://server/api/b/3" }
    ]
}

私の懸念は、ユーザーがリソースAを更新するときにリソースに何を含めるかを必ずしも知っているとは限らないことlist_bです。

あるリソースから別のリソースへのハイパーリンクを処理する場合、作成と更新はどのように機能する必要がありますか?クライアントはリンクの一部(id)を更新することを許可する必要がありますか、それともリンクの両方の部分を更新する必要がありますか?

注:別のアプローチがリソースAのサブURLを公開する可能性があることを知っています。これはlist_b、HTTP経由で操作可能なリソースとして公開できます(クライアントがリストリソース自体でPOST、PUT、およびDELETEを使用できるようにします)。ただし、Aに他のリソースタイプへの複数の参照が含まれている場合、これはあまり合理的ではないようです。別のフィールドを参照する各フィールドには、サブURLが必要になる可能性があります。これは、10以上のフィールドがある場合、扱いにくく、リソースを更新するために複数のHTTPリクエストを必要とします。

4

2 に答える 2

2

HATEOASはRESTfulインターフェースでリソースを相互に接続しますが、ここでは、説明している補助オブジェクトが独立したリソースとして本当に意味があるかどうかは明確ではありません。HATEOASの「AS」の部分は、WebページがWebアプリケーションの「リソース」として果たす役割を思い出させます。各Webページは実際にはアプリケーションの状態(この場合は「アプリケーション」は古典的な複数ページのWebアプリケーション)のインタラクティブな表現であり、他のリソースへのハイパーリンクはユーザーに他のアプリケーションの状態への遷移を提供します。

クライアントとして人間ではなくJavaScriptコードを使用するRESTfulWebAPIは、当然データアクセス指向であるため、そのリソース自体が「アプリケーション状態」の形をとる場合はほとんどありません。従来のWebアプリケーションでは、状態遷移図を描画して、状態間の接続、つまりリソー​​ス間の接続を明確に確認できます。RESTful APIでは、パッシブデータリソース間の境界は、クライアント/サーバーの相互作用やその他の微妙な力の効率によってさらに動機付けられます。

では、ここでの補助オブジェクト( "B")は、本当にファーストクラスのリソースとして表す必要がありますか?フロントエンドが、それらが参加しているアグリゲート( "A")とは関係なく、それらを列挙したり、アクセスしたりする場合がありますか?

答えが「いいえ」の場合、それらは明らかに「A」構造でhyptertextuallyで表されるべきではありません。ただし、答えは「はい」であり、独立したリソースとして参照する他のすべての補助オブジェクトを提供する十分な理由があると思います。この場合、アプリケーションはおそらくそれぞれを独自に操作する手段、または少なくともクエリを実行する手段を提供しているため、これらのリソースのすべてをサポートするために必要なルートとコントローラーの形式でのインターフェイス作業がある程度あります。それら(あなたの例のようなハイパーリンクを介して)。

この場合、「B」オブジェクトのコレクションを表すパス(「server / api / b」など)へのPOSTは、新しいリソースを作成するPOSTとして、応答の「location」ヘッダー値にURLを返すことができます。行う。ユーザーがWebページの「A」に属するリストに新しい「B」をインタラクティブに追加すると、フロントエンドは最初に新しい「B」をPOSTし、成功するとロケーションヘッダーからURLを取得します。次に、更新された「A」をPUTする前に、そのリンクを「A」オブジェクト内のリスト表現に組み込むことができます。

URLのテキストからID値を抽出することでバックエンドのカプセル化を破りたくなるので、ID値は少ししわになります。真のHATEOAS熱狂者は、RESTful APIに、特にクライアント側のカプセル化を破るようなフラストレーションを与えるために、難読化、ハッシュ化、またはその他の方法で理解できないURLを生成させます。新しい「B」オブジェクトのPOSTは、応答本文にIDを含む新しい「B」オブジェクトの完全な表現を返すため、クライアントはオブジェクト全体を再構成し、そこからIDを抽出して、絞り込みを行うことができます。リソース自体への結合であり、リソースを取得するためのRESTfulインターフェースの詳細ではありません。

于 2013-03-14T18:02:43.310 に答える
1

LINKまた、メソッドも確認する必要があります。

LINK /ResourceA/1 HTTP/1.1
Link: <http://example.com/ResourceB/3>; rel="list_b"
...

204 Yeah Fine, Whatever

これは、関係「list_b」を使用して/ ResourceB/3にリンクするように/ResourceA/1に指示します。

于 2013-05-29T13:05:30.600 に答える