2017-08-08 7 views
10

私はJSON APIに従おうとしています。 CRUDアクセスをネストされたリソース、つまり製品レビューに公開する必要があります。ネストされたリレーションシップをJSON APIのURLに反映する必要がありますか?

JSON APIを使用する前に、私はこのようなRESTインターフェースを期待したい:

GET /products/:product_id/reviews  - list reviews for a product 
POST /products/:product_id/reviews  - add a review for a product 
PATCH /products/:product_id/reviews/:id - update a review for a product 
DELETE /products/:product_id/reviews/:id - delete a review for a product 

を私はこのin the specような入れ子構造のいくつかの言及を参照してください。たとえば

を、URL写真のコメントになります。

/photos/1/comments

しかし、この構造がすべてのアクションを対象としているかどうかはわかりません。

一方、レビュー本体のrelationshipsの下でPOST本体に製品を指定すると、作成のためのPOST /products/:product_id/reviewsが冗長なように見えます。

一方、レビューを削除するときに商品IDを指定すると便利な場合は、DELETE /products/:product_id/reviews/:idがそれを行うには元気な方法だと思われます。 people argue about whether a request body is even allowed for DELETE requests

私はいくつかの要求ではなく他人のために巣ができます

GET /products/:product_id/reviews - list reviews for a product 
POST /products/:product_id/reviews - add a review for a product 
PATCH /reviews/:id     - update a review 
DELETE /reviews/:id     - delete a review 

をしかし、それは不気味矛盾しているようです。

GET /reviews  - list reviews for the product specified in params 
POST /reviews  - add a review for the product specified in params 
PATCH /reviews/:id - update a review 
DELETE /reviews/:id - delete a review 

しかし、それは厄介なようだ、と私はドキュメントから作られた最初の引用符と一致していないようです:

私は巣決してできました。

JSON APIを使用する場合、ネストされたリソースの関係がURLに反映されるべきですか?

答えて

9

私は同じ考えを持っているので、あなたの質問は本当に好きです。私はまだ誰も答えを残していないことに困惑しています。

私はJSON APIを1年以上プロダクションシステムで使用しており、私は2セントを提供したいと思います。

最初にJSON APIを使用するプロジェクトを開始したとき、ネストされていないリソースとネストされていないリソースは疑問でした。その後、ネストされていないリソースでは回避されていたネストされたリソースに関する問題が発生しました。

例の場合と同じパスを使用する場合は、GET /products/:product_id/reviewsエンドポイントを検討してください。 これを行うと、最初に製品のコンテキストでレビューを表示しているため、製品のレビューをネストするのは非常に意味があります。すべてが良いです。

その後、ユーザーとユーザーが作成したすべてのレビューを示すフロントエンドにページを作成します。 レビューを取得するためのエンドポイントは既に用意されていますが、新しいものを作成する必要があります。 GET /users/:id/reviews

GET /reviewsに最初のエンドポイントを入力すると、?filter[product_id]=:idのフィルタが追加されますが、そのエンドポイントに新しいフィルタを追加するだけで、IMOの意味を理解することができます。

私はネストされたリソースを使用しますが、GET /users/:id/email_settingsなどのシングルトンリソースと他の特別な場合にのみ使用します。

私の経験では、各リソースが他のリソースと独立していると考えられると、将来的にはより簡単になります。リソースとリソース間の関係が存在します。リソースは、APIのコンテキスト内で別のリソースを「所有」していません(ビジネスロジックのコンテキストでは別の話です)。

私はこの戦略に取り組んできましたが、既存のエンドポイントに新しい機能を追加したり、新しいエンドポイントを追加したりするときに、それがどれくらいうまく機能するかは驚いています。

+2

特定のリソースに対して正確に1つの正式なURIが存在するはずであるという考えに至りました。ネストされたリソースを使用すると、同じリソースの多くの場所で終了する可能性があります。 '/ products/1/review/1'と' '/ reviews/1''を参照してください。 重要な違いw.r.t. JSON APIは、[_relationship_ resources](http://jsonapi.org/format/#fetching-relationships)がこのアイデアに違反しているとは限りません。それらは、2つのものの間の_関係の標準的な場所です。 '/ products/1/relationships/reviews/1'は、これらのリソース間の関連を表します。 – Iamvery

+1

あなたの洞察を共有してくれてありがとうLasseと@iamvery!これが私が使い終わったアプローチです。 –

2

あなたがCQRSキャンプから来ている場合、なぜ安らかなAPIを設計するのが厄介なのかを理解するでしょう。当然のことながら、Queryアクション(GET)とMutationアクション(POST、PATCH、DELETE)は2つの異なる言語で話す必要があるため、扱いにくいです。 クエリアクションは自然に関係指向とデータリッチです。突然変異の行動はしません。したがって、関係エンティティ間のネストされたURLをトラバースするのは簡単です。 しかし、突然変異は、仕事のために十分な情報を提供するべきです。 Postの例のように重複していることもあります。あなたのDELETEの例のように時には欠けている。タスクには多くのリソースが必要な場合があります。

Facebook Graph APIまたはAzure Graph APIをチェックして、同じ問題を抱え、いくつかの良い解決策があるはずです。一貫したデザインに従うことが重要です。 一部のルールは次のとおりです。

  • 削除、常にリソースを直接更新します。
  • オブジェクトとメインの両方の関係を作成する場合は、ネストされたリソースでPOSTを使用します。二次的関係はBODYに入れなければならない。 2つの等しい関係がある場合は、両方のネストされたAPIを持つことを検討してください。
  • 多くのリソースに関連するタスクでは、偽のリソースに対してPOSTを使用します。タスクのための偽の関係に対する

    POST/transferfund

  • 使用POSTは、任意のHTTP動詞に合うことができませんでした。たとえば、あなたは、削除アクションのために体を持っている

    POST /リソース/ ID/deleteItForMeを使いたい {理由: "私はそれを嫌う"}私もこのフィットすることを追加したい

関連する問題