web-dev-qa-db-ja.com

さまざまな要求/応答タイプに対するDTOの再利用vs必要なもの/返すべきものの明示

ここでアンチパターンに陥らないかと思い始めたので、おすすめの方法を教えてください。

REST APIをさまざまなエンドポイントのセットで設計しています。リクエストとレスポンスのパラメーターをNice DTOにラップしたいと思っています。

たとえば、いくつかのエンドポイント:

public async Task<JobStateResponse> GetJobState(JobStateRequest request);
public async Task<JobDownloadRespose> DownloadJob(JobDownloadRequest request);
public async Task<CreateJobResponse> CreateJob(CreateJobRequest request);

問題は、これらの要求と応答が比較的類似したDTOであることです。次に例を示します。

public class JobStateResponse{
    public int TaskId {get;set;}
    public string ExternalId {get;set;}
    public State State {get;set;}
}
public class JobDownloadResponse {
    public int TaskId {get;set;}
    public string ExternalId {get;set;}
    public string JobContent {get;set;}
}

これらの基本クラスを作成して継承することを考えましたが、一部のプロパティが冗長になる可能性があります...つまり、メソッドが、正常に機能するために必要なパラメーターを明確に示していません。

つまり、7つのプロパティを持つDTOパラメータでAPIエンドポイントを公開するが、実際に必要なのは2つのサウンドだけです ...

一方、ほとんどのエンドポイントで個別のDTOを維持することはやり過ぎのように思われますと、メンテナンスの地獄です。

また、最後に必要なのは、いくつかの基本-基本クラスの複雑な関係ですリクエストの場合、これはさらに悪い保守問題になる可能性があるためです。

それでは、リクエスト<>レスポンス処理の適切なアプローチは何ですか?

編集:「意見に基づく」フラグについて-これを処理するためのベストプラクティスを探しています。複数の方法でできることは知っていますが、地雷やアンチパターンは避けたいです。また、これまでの答えにはかなり満足していると思います。

20
Bartosz

個別のシンプルなDTOは、あなたの人生を限りなく容易にします。それはより多くのコードを必要としますが、それは退屈で単純なコードであり、テストが容易であり、インターフェースを独立して変更および進化させることができます。

要求エンドポイントごとにDTOを作成し、応答ごとに個別のDTOを作成します。そうでなければ、あなたは結局悲しむでしょう。

複数のエンドポイントに共通の要素を見つけた場合は、それらを独自のオブジェクトに抽出し、両方に含めます。

そして、はい、ここでの継承の使用は間違っています。構図のパターンに固執すれば元気になります。

22
Rob Conklin

個別のDTOを使用すると、データアクセス呼び出しの動作によってデータ転送を最適化できます。また、公開したくないプロパティへのアクセスを制限することもできます。これはより多くのコードですが、公開されているものを正確に定義し、それを完全に制御します。

5
Mark Redman

エンドポイントごとのDTOを、要求と応答の2つのグループに確実に分離する必要があります。

ここで、継承について言えば、一般的な非特定のもの(たとえば、データをプラグインするリクエスト&レスポンスラッパーメッセージ)を含むベースリクエストクラスとベースレスポンスクラスを使用できますが、リクエスト間で継承を混在させたくありません。と応答側。

他の人がすでに指摘したように、最初は少しコードが増えますが、そうすることで壁にぶつかることはありません。逆に、それらを混ぜるとすぐに巨大なリファクタリングができるようになり、明確で別々の方法で開始するよりも多くの時間と神経を失うことになります。

2
dee zg