<aside> <img src="https://raw.githubusercontent.com/eirikmadland/notion-icons/master/v5/icon3/ul-github.svg" alt="https://raw.githubusercontent.com/eirikmadland/notion-icons/master/v5/icon3/ul-github.svg" width="40px" /> μ°Έμ‘° Github Code

</aside>

1. Data Validation

[Validation μˆ˜ν–‰ν•˜λ©΄μ„œ 데이터 λ°”μΈλ“œ ν•˜λŠ” DTO μž‘μ„± ]

public class CreateDeveloper {

    @Getter
    @Setter
    @AllArgsConstructor
    @NoArgsConstructor
    @Builder
    @ToString
    public static class Request{
        @NotNull    // λΉˆκ°’ ν—ˆμš© X
        private DeveloperLevel developerLevel;

        @NotNull
        private DeveloperSkillType developerSkillType;

        @NotNull
        @Min(0)     // μ΅œμ†Œ 0
        @Max(20)    // μ΅œλŒ€ 20
        private Integer experienceYears;

        @NotNull
        @Size(min = 3, max = 50, message = "memberId size must 3~50")
        // 데이터 크기 μ •μ˜ : μ΅œμ†Œ 3, μ΅œλŒ€ 50, Error λ©”μ‹œμ§€ μž‘μ„±
        private String memberId;

        @NotNull
        @Size(min = 3, max = 20, message = "name size must 3~20")
        private String name;

        @Min(18)
        private Integer age;
    }

    @Getter
    @Setter
    @AllArgsConstructor
    @NoArgsConstructor
    @Builder
    public static class Response{
        private DeveloperLevel developerLevel;
        private DeveloperSkillType developerSkillType;
        private Integer experienceYears;

        private String memberId;
    }
}

[Controller μˆ˜μ •]

@PostMapping("/create-developers")
public List<String> createdevelopers(
        @Valid @RequestBody CreateDeveloper.Request request
) {
    log.info("POST /create-developers HTTP/1.1 ");
    log.info("requset : {}", request);

    dmakerService.createDeveloper(request);

    return Collections.singletonList("Olaf");
}

2. Business Validation

[μ‚¬μš©μž Exception κ΅¬ν˜„]

@Getter
public class DMakerException extends RuntimeException {
    private DMakerErrorCode dMakerErrorCode;
    private String detailMessage;

    // μ—λŸ¬μ½”λ“œλ§Œ λ°›μ•„μ„œ 처리
    public DMakerException(DMakerErrorCode errorCode) {
        super(errorCode.getMessage());
        this.dMakerErrorCode = errorCode;
        this.detailMessage = errorCode.getMessage();
    }

    // μ—λŸ¬μ½”λ“œμ™€ μƒμ„Έλ©”μ‹œμ§€ λ°›μ•„μ„œ 처리
    public DMakerException(DMakerErrorCode errorCode, 
					String detailMessage) {
        super(detailMessage);
        this.dMakerErrorCode = errorCode;
        this.detailMessage = errorCode.getMessage();
    }
}
@Getter
@AllArgsConstructor
public enum DMakerErrorCode {
    NO_DEVELOPER("ν•΄λ‹Ήλ˜λŠ” κ°œλ°œμžκ°€ μ—†μŠ΅λ‹ˆλ‹€."),
    DUPLICATED_MEMBER_ID("MemberIdκ°€ μ€‘λ³΅λ˜λŠ” κ°œλ°œμžκ°€ μ—†μŠ΅λ‹ˆλ‹€."),
    LEVEL_EXPERIENCE_YEARS_NOT_MATCHED("개발자 레벨과 μ—°μ°¨κ°€ λ§žμ§€ μ•ŠμŠ΅λ‹ˆλ‹€."),

    INTERNAL_SERVER_ERROR("μ„œλ²„μ— 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€."),
    INVALID_REQUEST("잘λͺ»λœ μš”μ²­μž…λ‹ˆλ‹€.");

    private final String message;
}
private void validateCreateDeveloperRequest(CreateDeveloper.Request request) 
				throws DMakerException {
    // Business Validation
    DeveloperLevel developerLevel = request.getDeveloperLevel();
    Integer experienceYears = request.getExperienceYears();
    if (developerLevel == DeveloperLevel.SENIOR
            && experienceYears < 10) {
        throw new DMakerException(LEVEL_EXPERIENCE_YEARS_NOT_MATCHED);
    } else if (developerLevel == DeveloperLevel.JUNGNIOR
                && (experienceYears < 4 || experienceYears > 10)) {
        throw new DMakerException(LEVEL_EXPERIENCE_YEARS_NOT_MATCHED);
    } else if (developerLevel == DeveloperLevel.JUNIOR
            && experienceYears > 4) {
        throw new DMakerException(LEVEL_EXPERIENCE_YEARS_NOT_MATCHED);
    }

    developerRepository.findByMemberId(request.getMemberId())
            .ifPresent(developer -> {
                throw new DMakerException(DUPLICATED_MEMBER_ID);
            });
}