RESTでは、別々のエンドポイントを持つことよりもJSONペイロード内に識別子を含む

それで、想像して、私は雑誌への購読支払いがなされることができる終点を持っています。

購読にはさまざまな種類があります。例えば、毎週、2週間、1年、5年間など

サブスクリプションごとに、サブスクリプションエンドポイントへのJSON要求は少し異なります。たとえば、おそらく5年間の購読では、居住地の住所を尋ねたいかもしれませんが、毎週の購読では、おそらく気にしないでください。したがって、検証(およびビジネスロジック)は、購読タイプによってわずかに異なります。

問題は、エンドポイントをモデル化するための好ましい方法です。

  1. Have one single endpoint: /subscription in the JSON that is sent, you have a discriminator property. That is: { name: "Joe", Age: 66, subscription_type: "weekly | monthly | fortnight | yearly | etc" } So that in the implementation of /subscription you have code that performs different validation to the JSON request and executes different business logic depending on the value of the subscription_type
  2. Have separate endpoints for the different subscription types. For example: /subscription/weekly, subscription/monthly etc and have the implementation of each of these endpoints to only care about the validation and business logic specific to their subscription type.

私が述べたこれら二つ以外に可能な他の任意の選択肢は?このようなシナリオに対処するためのベストプラクティスはありますか?

1
nl ru de
あなたの定期刊行物が毎月出てくるが、ユーザーが毎週支払うことを望んでいるのであれば、どうなりますか?言い換えれば、要求された支払い方法が問題の雑誌に対して有効であることを保証する検証はありませんか?
追加された 著者 tim_yates,
これはRESTとは関係ありません。あなたの質問が言及しているように見えるのは、有効なURIの要件です。それはRFC 3986で対処されています
追加された 著者 dwtorres,

4 答え

リソースは一部の顧客の購読です。期間、開始日などは、購読に関する情報です。

リソースアドレスが customer/{id}/subscription /毎月顧客IDを指定して、どのようにして GET 購読タイプを取得しますか。

顧客の購読についての情報を得るために GET {id}/subscription を、新しい購読を作成するために PUT {id}/subscription を実行することができるようにしたほうがきれいです既存の購読を修正するにはPOST {id}/subscription

3
追加された
「購読」を必ず「顧客」から引き継ぐのであれば、なぜ「顧客」が必ずしも「パーティーの役割」として従うのではなく、そこから「パーティー」に進むのでしょうか。その一例として、金融システムは貸方と借方に直接基づいて設計されるべきだと私は確信しています。「誰」の詳細、「どこ」の詳細、そして「なぜ」の詳細は、この中核的な文脈の中では完全に無関係であり、「何」と「いつ」が適切であるだけです。
追加された 著者 dwtorres,

あなたの要求はRESTfulなアーキテクチャースタイルに直交しています。

RESTは単なる建築スタイルです。その仮定の1つは、あなたが他のプロトコルの中にあなた自身のプロトコルセマンティクスを定義してはいけないということであり、そして親スキームを参照することによってあなたのカスタム規約の詳細を難読化することです。

一例として、あなたはあなたのリソースを識別するために "URI"を使用することはできず、そしてRFC 3986の要求に違反します。あなたのプロトコルとして "HTTP"を使用していることを主張することはできず、 "GET"リクエストと共に冪等でないリクエストを送信することはできません。このようなことは、HTTPの要件の範囲内では意味がありません。

そのフレームワークの中では、RESTfulなアーキテクチャースタイルの主な貢献は、利用可能なアプリケーションの状態遷移をサーバーからクライアントに伝達する必要があるという概念です。


それはあなたがあなたの購読間の違いなしで区別を強制しようとしていてあなたのインターフェースを通してこの区別を伝播しようとしているかのように見えます。

リソースインターフェースがすべての "購読"で同じである場合は、そのリソースの表現力に意味のあるものを、属性の1つで正式に分割しても意味がありません。あなたのリソース識別子の中でこれをすることによって達成される唯一のものはあなたのサービス抽象化を通してあなたの内部サーバー実装を漏らすことです。

あなたが提供した情報から、あなたは単一の実体を持っているように見えます。したがって、さまざまな種類の「サブスクリプション」にわたって単一のインターフェースを設計するように努力する必要があります。

2
追加された

このようなシナリオに対処するためのベストプラクティスはありますか?

私は「あなたはどうやってこれをウェブサイトでやるの?」と尋ねたことがわかりました。あなたのデザインを評価するための非常に強力なツールです。

サブスクリプションごとに、サブスクリプションエンドポイントへのJSON要求は少し異なります。たとえば、おそらく5年間の購読では、居住地の住所を尋ねたいかもしれませんが、毎週の購読では、おそらく気にしないでください。

そのため、顧客からデータを収集するための複数のフォームがあるように思えます。そのユースケースで必要な情報を収集する週次形式と、異なるデータセットを収集する5年形式があります。これらの各フォームはaction属性を持ちます。フォームが送信されると、クライアントは適切なペイロードを作成し、そのフォームで記述されているエンドポイントに要求を送ります。

したがって、あなたの質問の核心は以下のとおりです。これらの異なるフォームはそれぞれ固有のエンドポイントを持つべきですか?それともエンドポイントを共有する必要がありますか?

少し別の言い方をすると、この選択の意味は何ですか?

RFC 7234には、キャッシュの無効化が記載されています。

キャッシュはセクション5.5 LocationおよびContent-Location応答ヘッダーフィールドのURIと同様に、href = "https://tools.ietf.org/html/rfc7230" rel = "nofollow noreferrer"> RFC7230 )安全でないリクエストメソッドに応答して、エラーでないステータスコードが受信された場合)。

言い換えれば、あなたが表現を GET したのと同じリソースに POST すれば、仲介者は以前に保存されたリソースの表現が追い出されるべきだと知ることができます。

つまり、たとえば、キャッシングプロキシをAPIエンドポイントの前に置き、正しい動作を「無料」で取得できるということです。同様に、関連するキャッシュを持っているクライアントは彼らのローカルキャッシングを無料で使うことができます。

もちろん、 PUT を使用して購読リソースを変更する場合または PATCH を入力した場合も同様です。安全でない要求はリソース自体に送信してください。そのため、キャッシュの無効化は想定どおりに機能します。

It's a trade; we accept the constraint upon our choice of endpoints, in exchange we get free caching. In 2008, Fielding wrote

RESTは、複数の組織にわたる長期にわたるネットワークベースのアプリケーションを対象としています。制約が必要ないと思われる場合は、使用しないでください。

をキャッシュすることは、すべてのAPIにとって強力な議論ではありません。あなたの場合にそれが意味を成さないなら、あなたはこの議論を特に説得力があると見なすべきではありません。 ドキュメントを読み、制約について理解してください。

1
追加された
コンピュータサイエンスのすべてには、ハードウェアの問題が2つしかありません。キャッシュの無効化、モノの命名、1回限りのエラー、およびキャッシュの無効化
追加された 著者 dwtorres,

2番目のモデル、間違いない。

ほとんどの場合、エントリ値で一貫性があるようにエンドポイントを分けることをお勧めします。

別の属性が一緒に送信された場合、別の属性を受け入れることができるエンドポイントを用意するのはよくありません。

  • 理解するのが難しい
  • 良いドキュメントを作成するのが難しい
  • メンテナンスが難しい
  • 異なるバージョンのリソースを作成するのが難しい場合(あなたの場合)。

ボーナス

あなたがタイプ情報なしで購読を保存することができるならば、私は提案をします:別々のPOSTで/subscription/に共通の情報を送り、各タイプにPOSTでそれぞれのタイプの特定の情報を送る/subscription/{id}/type/weekly//subscription/{id}/type /毎月/など。

0
追加された