1

私はdto(データ転送オブジェクト)を使い始めています。APIのシステムアーキテクチャを構築する最良の方法については疑問があります。DDDを使ってAPIを構築するためのdtoの作業

'B'、 'C​​'、 'D'との関係を持つドメインエンティティ 'A'を想像してください。私たちはすべての "A"を持つjsonリストを返すサービス 'S'を持っています。そのサービスに「ADTO」を作成し、「BDTO」、「CDTO」、「DDTO」と記入してください。別のサービス「S2」があり、特定のセットの「B」を返す必要がある場合、「C2DTOS」、「D2DTO」...の「B2DTO」の別のツリーを作成する必要があります。これは正しい方法ですか?

このように、DTOの巨大で複雑なツリーがあり、各ユースケースに固有のDTOがあります。

EDIT:

私はアセンブラの一部を忘れてしまいました。 DTOごとに異なるアセンブラを実装する必要がありますか?たとえば、エンティティAの場合、2つのDTOがあります。 A1AssemblerとA2Assemblerを同じアセンブラで使うことができますか?

+0

サービス境界が明確に定義されていないようです。あなたのSは、Aを保持し、追加なしでADTOを返すか、すべてのA、B、C、Dの知識と状態を持ち、これらのオブジェクトが読み込みモデルとして形成できるDTOを返す必要があります。 –

+0

問題は、ADTOはBDTO、CDTOなどで満たされていますが、サービスSはADTOのみを返します。どのように処理するのですか? DTOは別のDTOを保持できますか? –

答えて

1

あなたのDTOが間違っていると思います。あなたは2種類のDTOを持っています。 1)それらはあなたのドメインエンティティになることができます。その後ADTO、BDTO、CDTOを返すことができます。しかし、これらのDTOのはかなり一貫性があることができます(理由B2DTOがBDTOから任意の異なるだろう)

あなたはJSONはここ

{ 
Id: 1 
name: "foobar", 
$type: "A", 
B: [ { 
     name: "b-bar", 
     $type: "B"}] 
CIds: [ 2,23, 42] 
} 

を見てどうなるかを見れば、あなたがオブジェクトの2種類、いくつかの(Bさん)を参照してくださいサブオブジェクトとしてDTOに完全に返されます。他のもの(Cのようなもの)はIDで回され、別々に照会することができます。 Cのクエリーを実装しているのがS2なら、あなたは気にしません。

2)CQRSのようなアーキテクチャになると、別のDTOを取得します。 (射影またはコマンド)がありますが、DTOの命名にもこれが表示されます。例えば、 AListOnOverviewPageDTO、AUserEditDetailDTOなど

これは非常に異なる用途を表す投影であるため、異なるDTOを持つことは非常に意味があります。 (DDDでよく見られるような完全なオブジェクトではありません)

更新異なるDTOが必要な理由は2つあります。まず、各コールを個別に最適化することができます。たぶん、リストが速くなければならないので(CQRSを使用して)、正しいインデックスをデータに入れてlistDTOをより速く返すことができます。これにより、あなたはユースケースについてより簡単に理由を付けることができます。各DTOは1 usecase/screenを表します(そうでないと、userlistDTOで大文字小文字の区別が得られます。この場合、これらの3つのフィールドのみを設定する必要があります)。 さらにAPIが正直であることを確認する必要があります。決して空のデータを持つ「年齢」フィールドを返すことはありませんが、他の呼び出しは同じユーザーを返しますが、別の呼び出しでは同じ年齢のユーザーを返します。バックエンドが壊れて見えるようにします。しかし、/ users/listへの呼び出しと/ users/1/detailへの別の呼び出しがあった場合、詳細呼び出しによって特定のユーザーに関する詳細フィールドが返された場合は当然です

+0

ドメインエンティティ "User"と、すべてのユーザ(ここではuserListDTO)を取得するためのApiコール、そしてその後、すべてのユーザに追加情報を取得するための別のコールを想像してみましょう。 userExtraListDTOを作成する必要がありますか?そして、ここで年齢のユーザーの名前だけを取得する別の呼び出しです。 3種類の応答に対して3つのDTOを実装するのは正しいですか? (他のフィールドは空のままにします)。 答えがcase(この例では3)の実装であれば、アセンブラで同じ質問があります:3つの異なるアセンブラか、もう1つは汎用ですか? – Ijuhash

+0

はい、私はしばしば3つのDTOを作成します。それは2つの利点を持っています 1)セキュリティ。私はそれぞれのコール/ DTOへのアクセスを個別に制御できます。また、バックエンドはセキュリティの理由を簡単に判断できます。 2)私が返す情報について正直です。別の呼び出しが正しい(空ではない)年齢を返す空の時代を返すことは、非常に不愉快なAPIのためになります。 これらの3つのDTOはすべて同じアセンブリ内にありますが、それは問題ではありません – Batavia

+0

答えをありがとう。私は同じアセンブリを使用することは問題ではないと想像しました。 – Ijuhash

1

あなたのDTOは、あなたのクライアントに持ってほしい。通常、エンティティをDTOに「コピーする」べきではありません。あなたが世界と共有したくないフィールドがあるかもしれないからです。そのデータを入力したユーザーのIDを持つ「追跡」列を自動的に作成しているとします。そうでない場合は、パスワードフィールドを持つCustomerエンティティがあるとします。それがあなたのDTOの一部であることは望ましくありません。そのため、AutoMapperなどを使用する場合は、細心の注意が必要です。

DTOを設計するとき、クライアントがそのエンドポイントから特に必要とするものを考えます。ときにはDTOも同じように見えることがあります。また、あなたのDTOは、必要に応じて簡単にも複雑にもなります。 1つの狂気の例は、あなたがアーティスト、彼の歌、それらの歌の投票率といくつかの余分なデータを表示するページを言うことができます。

ユースケースで正当化できれば、そのすべてをDTOに入れることができます。彼らが行うすべてのDTOはデータを運ぶことです。

はい、サービスはDTOS(POCO)を返します。

また、DTOは命名規則です。 "dto"の接尾辞に惑わされないでください。クライアントからの「コマンド」はDTOですが、その場合はたとえばAddNewCustomerCommandという名前になります。

意味がありますか?

+0

ありがとうございます。私は、DTOはプレーンな情報だけを格納するキャリーバッグであり、サービスはドメインエンティティではなくDTOを返さなければならないことを知っています。コマンドについて話すとき、コマンドパターンについて話していますか?私が知る限り、コマンドパターンは1つのものであり、DTOは別のものです。 – Ijuhash

関連する問題