0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Spring Boot + Reactで記事投稿アプリを作成予定|DTOを作成してみた

Posted at

※学習中のため間違っている箇所があるかもしれません。

はじめに

今回はDTOを実装していきます。
DTOはServiceController間のデータをやり取りするための重要なオブジェクトです。
しっかりと使用方法を覚えていきましょう

DTOとは

DTOとはData Transfer Objectの略で、
データを他レイヤーへ転送するためのオブジェクトです。

DTOとEntityについて

DTOとEntityは構造が似ていても責務が異なるため、
明確に使い分ける必要があります。
ここでDTOの責務について簡単に記載します。

  • サービス層とプレゼンテーション層のやり取りを行う
  • 外部に公開すべき最小限のデータのみ保持する
  • Entityに含まれる機密情報を隠蔽し、レイヤー間の責務分離を実現します

つまり、DTOは必要最低限のデータを保持し、受け渡す責務を負っています。

一方Entity

  • ドメインモデルを表現し、DBとの永続化処理の中心
  • Rpository層を介して永続化されたデータの取得、更新、削除を行う

となっており、EntityDTOでは責務が異なります。
構造が似ている場合があっても、責務と利用範囲が異なるので、明確に理解しておきましょう。

今回は前回のサービス機能をもとにDTOを作成していきます。
記載しているのは代表的なDTOで構成は他と同じになっているので、
最小限のDTOだけ記載させていただきます。

DTOを作成

以下に今回作成した代表的なDTOを記述します。
他のDTOでも主な構造は同じなので今回は割愛します。

共通結果返却DTO

ResultDto

共通の結果を返却するためのDTOです。
主に処理結果やメッセージの返却を行います。

ResultDto.java
import lombok.Builder;
import lombok.Getter;

/***
 * 結果返却DTO
 * Service内での処理結果共有で利用する
 * Controllerからの返却はしない
 */
@Getter
public class ResultDto {
    
    /***
     * 処理結果
     */
    private final boolean result;

    /***
     * メッセージ
     * 成功の場合もメッセージを設定
     */
    private final String message;

    /***
     * 初期設定用コンストラクタ
     * @param result
     * @param message
     */
    @Builder
    public ResultDto(boolean result, String message){
        this.result = result;
        this.message = message;
    }
}

レスポンス用DTO

GetArticleDetailDto

レスポンス用のDTOです。
DBから取得した値を設定するため、
アノテーションでのバリデーションは行いません。

GetArticleDetailDto.java
import java.time.LocalDateTime;


import lombok.Builder;
import lombok.Getter;

/***
 * 記事詳細表示用DTO
 * 記事の基本的な情報を保持する
 */
@Getter
public class GetArticleDetailDto {

    /***
     * タイトル
     */
    private final String title;

    /***
     * 内容
     */
    private final String content;

    /***
     * 表示フラグ
     */
    private final boolean releaseFlg;

    /***
     * 作成日
     */
    private final LocalDateTime createdAt;

    /***
     * 更新日
     */
    private final LocalDateTime updatedAt;

    /***
     * 初期設定用コンストラクタ
     * @param title
     * @param content
     * @param releaseFlg
     * @param createdAt
     * @param updatedAt
     */
    @Builder
    public GetArticleDetailDto(String title, String content, boolean releaseFlg
    , LocalDateTime createdAt, LocalDateTime updatedAt){
      this.title = title;
      this.content = content;
      this.releaseFlg = releaseFlg;
      this.createdAt = createdAt;
      this.updatedAt = updatedAt;
    }
}

リクエスト用DTO

InsertArticleDetailDto

リクエスト用のDTOです
受け取った情報をテーブルへ保存します。

InsertArticleDetailDto.java
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Builder;
import lombok.Getter;

/***
 * 記事投稿用DTO
 * 記事投稿時に必要なデータを保持する
 */
@Getter
public class InsertArticleDetailDto {

    /***
     * ユーザーID
     */
    @Min(0)
    private final int userId;

    /***
     * タイトル
     */
    @NotBlank
    @Size(max=50)
    private final String title;

    /***
     * 内容(本文)
     */
    @NotBlank
    @Size(max=255)
    private final String content;

    /***
     * 公開フラグ
     */
    private final boolean releaseFlg;

    /***
     * 削除フラグ
     */
    private final boolean deleteFlg;

    
    /***
     * 初期設定用コンストラクタ
     * @param userId
     * @param title
     * @param content
     * @param releaseFlg
     * @param deleteFlg
     */
    @Builder
    public InsertArticleDetailDto(int userId, String title, String content, boolean releaseFlg, boolean deleteFlg){
      this.userId = userId;
      this.title = title;
      this.content = content;
      this.releaseFlg = releaseFlg;
      this.deleteFlg = deleteFlg;
    }
}

削除用DTO

記事削除用のDTOです。
削除フラグを更新する際に使用します。

UpdateUserDeleteFlgDto

UpdateUserDeleteFlgDto.java
import lombok.Builder;
import lombok.Getter;

/***
 * ユーザー削除用DTO
 * 削除フラグを保持する
 */
@Getter
public class UpdateUserDeleteFlgDto {

    /***
     * 削除フラグ
     */
    private final boolean deleteFlg;

    /***
     * 初期設定用コンストラクタ
     * @param deleteFlg
     */
    @Builder
    public UpdateUserDeleteFlgDto(boolean deleteFlg){
        this.deleteFlg = deleteFlg;
    }
}

バリデーションに関して

DTOはデータの受け渡し用クラスです。
そのためバリデーションは基本的なものだけを使用し、
詳細な処理はService層で行う予定です。

基本的にバリデーションはEntityではなくDTOServiceで行うべきだと考えています。

アノテーションの説明

@Builder

@Builderをコンストラクタまたはメソッドに付与することで、
以下のように直感的な形式でインスタンス生成ができるようになります。

InsertArticleDetailDto.builder()
  .userId(ユーザーID)
  .title(タイトル)
  .content(内容)
  .releaseFlg(false)
  .deleteFlg(false)
  .build();

また、今回は使用していませんが、フィールドにListSetなどコレクション型を使用している場合
@Singularを付与することにより要素を1件ずつ追加する形式のビルダーメソッドが生成されます。

public class User {
    String name;
    String email;

    @Singular("content")
    List<String> contents;
}
public class Test {
    User user = User.builder()
        .name("モス・バーガー")
        .email("MosLike@gmail.com")
        .content("コンテンツ1")
        .content("コンテンツ2");
}

このように記述することで、引数の順序を気にせず読みやすくなります。
フィールドの増減があってもコードの修正は最小限で済むので
拡張性、保守性の高い設計が可能です。

まとめ

今回はDTOの解説をしました。
DTOEntityの違いを明確にして、有効に使用できるようにしていきましょう。

次回以降

  • Service,Controller
  • React連携

今回の記事が少しでもspring boot初学者の助けになれば幸いです。

前:Spring Boot + Reactで記事投稿アプリを作成予定|Flyway入門:DBマイグレーションの基礎からテーブル作成・データ挿入まで解説してみた

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?