2

RoomとPersonの2つのエンティティ/オブジェクトを含むWebサービスを想像してください。ここで、RoomはRoom.Occupantsプロパティコレクションを介してその中の人々を公開します。各エンティティにはLastModifiedの日付があります。

部屋の新しい表現が1人の居住者を削除してサービスにPUTされた場合、これは部屋のLastModifiedを変更する必要がありますか?

答えには、キャッシングに影響があります。

RoomIdがNULLに設定されているため、実際に変更されたエンティティはPersonであると見なすことができます。

ただし、日付が変更されたhttp ../ roomsへの条件付きリクエストでは、居住者を含むRoomの完全な表現の変更を反映できません。

部屋のLastModifiedを変更する必要があるという見方をする場合は、Personがサービスに書き込まれ、そのRoomIdが変更されるたびに、おそらく2つの部屋のタイムスタンプを更新する必要があります

そして、その人がPersonalBelongingsのコレクションを持っている場合はどうなりますか?これはすぐに手に負えなくなる可能性があるので、この複雑さをすべて回避するために、オブジェクトの表現は関連するコレクションの表現を除外する必要がありますか?

ルーク

4

4 に答える 4

3

ドメインで何が意味をなすかを定義するのはあなた次第です。

誰かが部屋を出るとき、それは部屋を「変更」しますか?正解は1つではないと思いますが、比喩から流れる直感は「いいえ」です。誰かが出入りしても部屋は変更されません。 これは、実際の部屋の動作の常識的な理解ですが、部屋と人を例のタイプとしてのみ使用していることは理解しています。実際のシナリオの問題はそれほど明確ではない可能性があります。

重要なことは、単に一貫性を保つことです。

最初のステップは、「存在する部屋にはPUTは許可されていません」と言うことです。PUTを介して「部屋を追加」することを不可能にすることができます。これにより、最初のシナリオの可能性がなくなり、部屋の人数が1人少なくなります。ある部屋から次の部屋に人を「移動」するには、特定のIDを持つ人にPOSTすることができます。

一方、部屋の居住者のリストを更新するために、部屋にメッセージをPOSTすることもできます。その場合、逆POSTで人を動かすことを許可したくない場合があります。

どのオプションを選択するかはあなた次第です-それが一貫していて賢明である限り、それは問題ありません。


もう1つの合理的な手順は、「LastModified」に適切な名前を付けることです。部屋と人のシナリオでは、より適切な名前は「LastContentsChange」または「LastOccupantsChange」である可能性があります。

次の合理的な質問は、私のアプリは、部屋の占有者のセットが最後に変更された時間を知る必要がありますか?そしてもちろん、それはあなただけが答えることができる質問です。

したがって、繰り返します。暫定的な設計上の決定を行い、その設計を実際に使用する場合の影響について考えます。次に、設計上の決定のいくつかを再検討して変更し、いくつかの新しいテストを行います。等々。

アイデアを試すためだけに、簡略化されたバッキングストアを使用して、デザインのプロトタイプを迅速に作成できると役立つ場合があります。

于 2012-07-03T15:48:54.210 に答える
3

エンティティやオブジェクトなどの用語を使用して REST ベースのシステムを定義し続けると、このような質問に苦戦することになります。REST はリソースと表現を扱います。これは些細な言葉遊びのように思えるかもしれませんが、このような問題に対処する際には大きな違いを生む可能性があります。

HTTP が気にする LastModified 日付は、表現の最終更新日です。私たちが懸念しているリソースが/room/45/occupants、部屋にいる人を表現し、誰かが部屋を出たところにある場合、表現に新しい LastModfied 値が必要であることは間違いありません。

REST インターフェイスの背後に隠されている room エンティティと person エンティティに何が起こるかの詳細は、まったく別の問題です。

リソースと表現の設計は、ドメイン エンティティがそれらのエンティティを格納するために使用されるデータベース構造と異なるのと同じように、ドメイン エンティティの設計とは異なります。

于 2012-07-03T16:19:50.230 に答える
1

ここで、古典的な鶏が先か卵が先かという問題で終わります。あなたは人が部屋の「外」に人生を持っているかどうかを決定しなければなりません。この場合、RoomIdがNULLのPersonsを見つけることができます。また、Personsは部屋のに住むため、Room.occupantsはPersonsへの参照(URL)を保持します(Personsを含むのではありません)。

Personsが部屋内にのみ存在する場合、Personsのすべてのコレクション管理はRooms内で行われ(新しいPersonを追加、1つ削除)、LastModified、占有番号などを効果的に変更/更新できるため、RoomIDがNULLのPersonsを持つことはできません。

次に、誰がトランザクションを管理するかを決定する必要があります。2番目のケース(個人は部屋の外に住んでいない)では、部屋自体にすべての状態が保存されるため、状態を更新するためのトランザクションは必要ありません(個人を削除または追加するだけで、部屋の状態が変更されます)。

最初のケースでは、部屋と人が相互に関連していることに注意してください。トランザクションがクライアントによって管理されている場合、クライアントは、個人を削除するときに必要な手順を常に実行するようにする必要があります。あれは:

  1. 人を削除する
  2. 部屋をPUTで更新します(個人の削除を反映するように居住者の参照を変更します)

サーバーで状態管理が実行されている場合、個人を削除すると、変更される部屋が作成されます。これにより、Personが削除されたときにRoomのコピーが強制的に無効になり、Personへの変更をRoomにカスケードする(つまり、LastChangedを更新する)のはサーバーの責任です。これは、サーバーにハードコードされたロジックです。

于 2012-07-03T15:52:00.810 に答える
1

一般に、あるリソースの変更は、以前にフェッチされたそのリソースを含むコレクションが無効になったことを意味すると思います。そのコレクションを取得するための新しい要求には、更新されたヘッダーが含まれているHEADと予想されます。GETLast-ModifiedETag

リソースとドメイン エンティティの違いについては、@Darrel Miller が正しいと思います。私にとって、これはさらに、それらのライフサイクルが異なり、個別に追跡する必要があることを意味します. 私の見方では、1 つのリソースの変更は、関連するコレクション リソースの変更をトリガーします。

そうは言っても、物事が手に負えなくなることなく、どのように実装しますか? リソースの状態がデータベースに保存されているのを見てきました (エンティティとは別)。URL を日付スタンプにマッピングするのと同じくらい簡単かもしれませんが、実際にはリソースのレイアウトに依存します。

更新に関しては、データベース トリガーを使用してリソースの状態を更新するのを見てきました。それは簡単ですが。スケーラブルではなく、単に面倒だと思います。私が最も気に入っている戦略は、サービス実装の内部でアプリケーション イベントを作成することです。これにより、リソースが変更されるたびにイベントを非同期に発行できます。イベント ハンドラーは、それに応じて他のリソースの状態を更新します。アプリケーション イベントを実装する多くの方法を見てきました。履歴のログ記録や記録に似ているため、アプリケーション イベントは分野横断的な関心事であると考えています。したがって、私はAOPを使用するのが好きですが、機能するものは何でも使用する必要があります。

于 2012-08-24T17:05:28.137 に答える