3

これは、私がこの場所で持っているのと同じ質問を見つけることができなかった数少ない瞬間の 1 つなので、私の問題を説明しようとしており、アイデアの助けを得たいと思っています!

まあ言ってみれば...

次のようなエンティティ/リソースを持つ可能性のあるドメイン モデル用の RESTful API を設計したいと考えています。

class Product
{
    String id;
    String name;
    Price price;
    Set<Tag> tags;
}


class Price
{
    String id;
    String currency;
    float amount;
}


class Tag
{
    String id;
    String name;
}

API は次のようになります。

GET /products
GET /products/<product-id>
PUT /prices/<price-id>?currency=EUR&amount=12.34
PATCH /products/<product-id>?name=updateOnlyName

参照を更新する場合:

PATCH /products/<product-id>?price=<price-id>
PATCH /products/<product-id>?price=

製品の価格参照を別の既存の価格に設定するか、この参照を削除することができます。

しかし、どうすれば既存のタグの新しい参照を製品に追加できますか?

その参照をリレーショナル データベースに格納したい場合は、その多対多リレーションシップ用のリレーションシップ テーブル「products_tags」が必要でした。これにより、明確な解決策が得られます。

POST /product_tags [product: <product-id>, tag: <tag-id>]

しかし、ドキュメントベースの NoSQL データベース (MongoDB など) は、これを各製品の 1 対多の関係として格納できるため、関係を保存するために作成する必要がある「新しいリソース」をモデル化する必要はありません。

しかし

POST /products/<product-id>/tags/ [name: ...]
    creates a new Tag (in a Product),

PUT /products/<product-id>/tags/<tag-id>?name=
    creates a new Tag with <tag-id> or replaces an existing 
    Tag with the same id (in a Product),

PATCH /products/<product-id>?tags=<tag-id>
    sets the Tag-list and doesn't add a new Tag, and

PATCH /products/<product-id>/tags/<tag-id>?name=... 
    sets a certain attribute of a Tag.

だから私はこれにリンクする何かを言いたいかもしれません:

ATTACH /products/<product-id>?tags=<tag-id>
ATTACH /products/<product-id>/tags?tag=<tag-id>

ポイントは次のとおりです。

新しいリソースを作成したくありません。

リソースの属性を設定したくないのですが、

セットである別のリソース属性にリソースを追加したいと考えています。^^

すべてはリソースに関するものなので、次のように言えます。

リソースを別のリソースにアタッチしたい。

私の質問:どの方法が適切で、URL はどのように表示されますか?

4

1 に答える 1

3

REST はアプリケーションの状態ドライバーであり、エンティティの関係を反映することを目的としていません。

そのため、REST には「データベースでこれが当てはまる場合」はありません。とはいえ、かなり良い URI があります。

あなたはIDについて話します。タグとは?タグは単純な文字列ではありませんか? なぜIDがあるのですか?その ID がその名前文字列ではないのはなぜですか?

なぜ持っていないのPUT /products/<product-id>/tags/tag_name=ですか?

PUT は冪等であるため、基本的には、によって参照される製品のタグの存在を主張していますproduct-id。このリクエストを複数回送信する201 Createdと、初回と200 OK次回が取得されます。

単一の Web サーバー上で単一の同時ユーザーが実行され、リクエストに同時実行がない単純なシステムを構築している場合は、ここで読むのをやめてください。

途中で誰かがそのタグを削除すると、次の put リクエストでタグが再作成されます。これは、あなたの望むことですか?

楽観的同時実行制御では、ドキュメントの ETag aを毎回渡し、サーバーに409 Conflict新しいバージョンbがあり、差分をa..b調整できない場合は戻ります。タグの場合は、PUT 動詞と DELETE 動詞を使用しているだけです。そのため、調整を比較/確認する必要はありません。

単一のサーバー上で実行される、最初の書き込み者が優先するセマンティクスを備えた、ある程度高度な並行システムを構築している場合は、ここで読むのをやめてください。

そうは言っても、トランザクションの境界を考慮していないと思います。何を変更していますか?リソース?いいえproductリソースの値オブジェクトを変更しています。そのタグ。したがって、リソースのモデルによれば、 を使用する必要がありますPATCH。並行性を気にしますか?さて、PATCH に関しては、さらに多くのことを考える必要があります。

HTTP PATCH の RFC には、次のように書かれています。

ただし、PATCH を使用すると、囲まれたエンティティには、現在オリジン サーバーに存在するリソースを変更して新しいバージョンを生成する方法を説明する一連の指示が含まれます。PATCH メソッドは、Request-URI によって識別されるリソースに影響を与えます。また、他のリソースに副作用がある場合もあります。つまり、PATCH を適用することで、新しいリソースを作成したり、既存のリソースを変更したりできます。

[RFC2616] のセクション 9.1 で定義されているように、PATCH は安全でも冪等でもありません。

あなたの頭に変な考えを入れるのはもうやめようと思います。この道をもう少し続けてほしい場合はコメントしてください;)。できることは他にもたくさんあります。

于 2012-04-05T10:36:16.063 に答える