DTO]DTOの使用範囲については、


このプロジェクトでDTOを初めて使用しました.
初めてDTOを使うときに疑問に思うDTOの使用範囲は何ですか?
エンティティとDTOの変換プロセスと時点をどのように区別するかをチームと議論し、決定したときの感想を記録します.

DTOとは?


まず、DTOは、階層間でデータを交換するためのデータ転送オブジェクトの略である.
まずDTOが現れる原因を考える.
クライアントと直接対話するコントローラは、データベースに関連付けられたエンティティを直接使用するのではなく、データのインポートにのみ使用します.
DTOは、レイヤ間でのみデータを交換するために使用され、他の論理を含める必要はなく、通常はGetterおよびSetter関数のみが実装される.

[ソース:DAO、DTO、Entityクラス差異]

ValidatorとDTO(アプリケーション)


Springでは、DTOとvalidatorがクライアントからのデータが適切かどうかを確認できます.
まずgradleにspringboot stater検証を追加します.
必要なDTOを作成すると、コントローラは@validでリクエストを確認できます.
ex)実際のプロジェクト応用内容.
public class CreateChallengeDTO {

	@NotBlank
	private String name;

	@NotNull
	private String description;

	@NotNull
	private Boolean isPrivate;

}
@PostMapping(value = "")
public ResponseEntity<ResponseChallengeDTO> createChallengeAPI(@Valid @RequestBody CreateChallengeDTO createChallengeDTO,
															   @AuthenticationPrincipal User user){
	Challenge createdChallenge = challengeService.createChallenge(createChallengeDTO, user);
	return ResponseEntity.status(HttpStatus.CREATED).body(ResponseChallengeDTO.convertDTO(createdChallenge));
}
@NotBlank、@NotNull、@NotEmptyなどの条件を使用すると、必要なすべての情報が含まれているかどうか、ルールに従っているかどうかを簡単に判断できます.
このようにspringは、クライアントとサーバとの間でDTOを送信することによって、Entity内の情報を非表示にし、DTOを使用してEntityの安定性を確保することができる.

🤔 DTOの適用範囲は?


クライアントとサーバの間でDTOを使用する方法を知っていますが、疑問があります.
DTOがレイヤ間でデータを交換するために使用される場合は、次のコードを記述する必要があると思います.
  • コントローラ-サービスはDTOを使用します.
  • RepositoryはEntityを使用する必要があります.
  • したがって、コードを記述する方法は次のとおりです.
  • コントローラは、DTOをそのままサービスに渡す.
  • サービスからEntityに変換し、ロジックを処理します.
  • 論理を処理し、返されるEntityはResponseDTOに変換される.
  • ResponseDTOをコントローラに送信し、クライアントに送信します.
  • すなわち、サービスは最終的に「エンティティからDTO」への変換を担当し、各階層間でDTOを伝達する.

    😢 問題が発生する


    「別のサービスから現在のサービスを呼び出したいのですが、ResponseDTOに戻ると問題になります」
    上記のようにサービス側からDTOを厳格に送信するために、コントローラは、顧客に伝達された情報のみをDTOとして送信し、コントローラとサービスの結合を増やした.
    これは、サービスがクライアントに送信するコンテンツを知ってDTOに変換し、サービス関数がコントローラの外にないことを意味します.(クライアントに送信するコンテンツのみが含まれているため)
  • コントローラを除き、サービスは利用できません.
  • クライアントに情報をサービスで知って伝える必要があります.
  • これらの問題を解決するために、私たちは次のように考えています.
  • サービスはEntityを返します.
    利点:サービスの自由度が向上します.
    欠点:Entityをコントローラに転送します.DTOの概念が破壊された.
  • モデルと同じDTOを作成し、それを返します.
    利点:コントローラに加えて、エンティティ情報を簡単に取得し、コントローラと隔離し、DTOの概念を遵守することができます.
    欠点:コードが増加します.
  • チームメンバーとの考慮を経て、2番を選択し、以下の修正を行いました.
  • クライアントから送信されたcreateDTO、modifyDTO->DTOに変更します.
  • DTOは、サービスに転送される.
  • サービスは、DTO->エンティティ変換、論理->DTOを返します.
  • コントローラから応答DTOに変換され、クライアントに転送される.
  • DTOの概念を厳格に守りながら、サービスの自由度を高めることができます.

    🔥 問題が発生する


    「クライアントがサービスから送信した情報が何であるかを明確に理解する必要があります.」
    サーバ内でDTOと厳密に通信するためには,従来の手法ではモデルと同じDTO通信のみが行われていた.
    問題は、クライアントが送信するDTOの情報が要求ごとにフィールドが異なるかどうか(id、name、members...).サービスにはDTOフィールドがすべて存在するため、コントローラからのDTOフィールドを「予期せぬ」使用する必要があります.
    逆に、GETではフィールド値がない場合にnullPointエラーが発生し、開発者のエラーが発生する可能性があります.
  • サービスは、コントローラからのすべてのフィールド値を理解する必要があります.
    (フィールドはすべてのDTOを提供するため)
  • は、ファイル内でフィールド値を繰り返し表示し続け、疲労度が増加し、エラーの可能性も高い.
  • 最終的には、コントローラが私たちに与える方法を変えることにしました.
  • コントローラが提供する値は、クライアントが送信するDTOを保持する.
  • フィールドの値を出して、一人一人に1つ送ります.
  • フィールド値の抽出と送信方法について,パラメータ順序などの類似の関数を増やすとコードの管理が困難になると考えられるため,方法を選択した.
    これにより,モデルと同じDTOを遵守する必要がなくなる.(Controller->サービスはモデルと同じDTOを使用しないため)

    🖐 われわれの結論


    つまり、最終的には
  • 型のようなDTOは現在必要ではないと思います->削除します.
  • エンティティを送信するが、コントローラおよび他のサービスによってエンティティを変更するコード
  • の作成は禁止される.
    そこで,ResponseDTOクラスでのみdtoEntity関数を作成し,コントローラが返すリスクを管理することにした.
    プロジェクトが大きくなり、コード管理が困難になると、entityの変更を予測することは困難になります.
    これにより、DTOを厳密に変更してモデルに戻ることができますが、この方法で続行することにしました.
    DTOの概念だけを学ぶとき、私たちは「もともと~~で使われていた」ことしか認識していませんが、実際のコードを作成して適用するとき、私たちはいくつかのあいまいなところに触れて、もっと知っているようです.
    実際,DTOやEntityをどこで変換するかは,環境や環境によって柔軟に適用される場合があり,人によって異なる場合がある.
    また、DTO(モデルなど)への執着により、いくつかの問題が発生する可能性があります.これらの問題をある程度受け入れながらコードを書く方法を学んだ可能性があります.
    違う意見や良い意見があればコメントに書いてください🤗
    長いコメントありがとうございます
    +追加する内容や不足点があれば、メッセージを残してください!:)
    >>プロジェクトコードを表示します。<<