1
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?

Java DTO and Domain に対する整理

Posted at

javaのドメインモデルとdtoを開発しながら問題になる部分を整理しました

1 . DTO とドメインなぜ 可変不変 を分けるのか?

階層 推奨する性質 理由
DTO(転送オブジェクト) 可変でも問題なし
― デフォルトコンストラクター+setter が Jackson/JPA と最も相性が良い
直列化・逆直列化専用。ビジネスロジックを持たないため、可変でも整合性リスクが小さい
ドメインモデル 不変recordfinal フィールド) 生成時にのみ整合性を検証 → 一貫性保証/スレッド安全/テスト容易

まとめ ― 不変性は ビジネスルールを抱えるレイヤ にだけ適用すれば十分。


2. Jackson 逆直列化 3 パターン

パターン コード例 特徴
① デフォルトコンストラクター+setter java @NoArgsConstructor class Foo { String name; void setName(...); } 実装が最も簡単。final フィールドには使えない
@JsonCreator + @JsonProperty java @JsonCreator Foo(@JsonProperty("name") String n) 完全不変 DTO が可能。全パラメータに @JsonProperty 必須
record(Java 14+) java public record Foo(String name,int value) {} 生成子・getter 自動生成、final フィールド OK。Jackson 2.12+ なら追加設定なし

-parameters オプションを付ければ(@JsonProperty なしでも)通常のコンストラクター名推論が可能。


3 . 実践コード例

3-1. 転送 DTO ― TemperatureSensorDto(可変)

@Getter @Setter @NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = false)   // additionalProperties=false を反映
public class TemperatureSensorDto {
    private String  name;
    private Double  value;
    private String  unit;   // "Celsius" | "Fahrenheit" | "Kelvin"
}

3-2. ドメインオブジェクト ― TemperatureSensor(不変)

public record TemperatureSensor(String name,
                                double value,
                                Unit unit) {
    public TemperatureSensor {
        if (name == null || name.isBlank()) throw new IllegalArgumentException("name");
        if (unit == null) throw new IllegalArgumentException("unit");
    }
    public enum Unit { CELSIUS, FAHRENHEIT, KELVIN }
}

3-3. マッパー(MapStruct)

@Mapper(componentModel = "spring")
public interface SensorMapper {
    TemperatureSensor toDomain(TemperatureSensorDto dto);
    TemperatureSensorDto toDto(TemperatureSensor domain);
}

4 . レイヤーごとの責務整理

┌─ REST / Kafka / GraphQL ──────────────────────────────────────────┐
│  TemperatureSensorDto  (可変) ← JSON 直列化/逆直列化         │
└─────────────▲  Mapper  ▼────────────────────────────────────────┘
┌─ Service / Domain ───────────────────────────────┐
│  TemperatureSensor(record・不変)               │
│  ビジネスロジック・整合性保証                    │
└─────────────────────────────────────────────────┘
  • DTO を変更してもドメインロジックへの影響は最小限
  • record により「不変 + 生成時検証」をシンプルに実現

5 . チェックリスト

チェック項目 ポイント
DTO に final フィールドはある? setter パターンなら final を避ける。不変 DTO が欲しければ record + -parameters@JsonCreator を使う
@JsonCreator 利用時 各パラメータに @JsonProperty を付与し、クラスにつき 1 個にする
JSON の "enum" Java 予約語なのでフィールド名を変更し、@JsonProperty("enum") でマッピング
追加フィールドの拒否 @JsonIgnoreProperties(ignoreUnknown = false)additionalProperties:false を反映
record サポートバージョン Jackson 2.12 以上 & JDK 14 以上が必要
1
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
1
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?