개발자 생성

김태은·2022년 4월 30일
0

데이터 벨리데이션 적용

  • CreateDeveloper 생성 -> request, response로 데이터 나눔
  • @NotNull, @Min, @Max, @Size 등 데이터 벨리데이션 적용
package com.fastcampus.programming.dmaker.dto;

import com.fastcampus.programming.dmaker.type.DeveloperLevel;
import com.fastcampus.programming.dmaker.type.DeveloperSkillType;
import lombok.*;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class CreateDeveloper {

    @Getter
    @Setter
    @AllArgsConstructor
    @NoArgsConstructor
    @Builder
    @ToString
    public static class Request{
        @NotNull
        private DeveloperLevel developerLevel;
        @NotNull
        private DeveloperSkillType developerSkillType;
        @NotNull
        @Min(0)
        @Max(20)
        private Integer experienceYears;

        @NotNull
        @Size(min = 3, max = 50, message = "memberId size must 3 ~ 50")
        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){
        // GET /developers HTTP/1.1
        log.info("request : {}", request);
        
        return dMakerService.createDeveloper(request);

@Valid@RequestBody앞에 붙여줘야 validation 적용이 됨

log로 request정보를 알아보기 위해 @ToString을 request에 추가

비즈니스 벨리데이션 적용

  1. 먼저 DMakerException 생성 - 예외 처리
package com.fastcampus.programming.dmaker.exception;

import lombok.Getter;

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

        //기본 에러 메시지
        public DMakerException(DMakerErrorCode errorCode){
                super(errorCode.getMessage());//RuntimeException에 담아줄 데이터를 넣어줌
                this.dMakerErrorCode = errorCode;
                this.detailMessage = errorCode.getMessage();
        }

        //디테일 메시지
        public DMakerException(DMakerErrorCode errorCode, String detailMessage){
                super(detailMessage);//RuntimeException에 담아줄 데이터를 넣어줌
                this.dMakerErrorCode = errorCode;
                this.detailMessage = detailMessage;
        }
}

-> RuntimeException 클래스를 extends함
-> DMakerErrorCode 클래스를 enum 클래스로 생성

package com.fastcampus.programming.dmaker.exception;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum DMakerErrorCode {
    NO_DEVELOPER("해당되는 개발자가 없습니다."),
    DUPLICATED_MEMBER_ID("MemberId가 중복되는 개발자가 있습니다."),
    LEVEL_EXPERIENCE_YEAR_NOT_MATCHED("개발자 레벨과 연차가 맞지 않습니다."),

    INTERNAL_SERVER_ERROR("서버에 오류가 발생했습니다."),
    INVALID_REQUEST("잘못된 요청입니다.");

    private final String message;
}
  1. DMakerService의 createDeveloper 함수 생성
  • validateCreateDeveloperRequest 추가
    -> developer 을 생성하기 전 비즈니스 벨리데이션을 통해 조건에 맞지 않은 것은 exception으로 던짐
  • @Transactinal 어노테이션 적용

  • validateCreateDeveloperRequest 함수
    -> 개발자 레벨과 연차를 확인해 레벨과 연차가 맞지 않다면 Exception을 던짐
    -> 이미 똑같은 memberId가 있다면 Exception을 던짐

 private void validateCreateDeveloperRequest(CreateDeveloper.Request request) {
        //business validation

        validateDeveloperLevel(
                request.getDeveloperLevel(),
                request.getExperienceYears()
        );

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

    }
  • validateDeveloperLevel 함수
private void validateDeveloperLevel(DeveloperLevel developerLevel, Integer experienceYears) {
        if(developerLevel == DeveloperLevel.SENIOR && experienceYears < 10){
            throw new DMakerException(LEVEL_EXPERIENCE_YEAR_NOT_MATCHED);
        }

        if(developerLevel == DeveloperLevel.JUNIOR && experienceYears > 4  ){
            throw new DMakerException(LEVEL_EXPERIENCE_YEAR_NOT_MATCHED);
        }
    }

-> 비즈니스 벨리데이션 적용 완료

  • 이후 builder 사용해 developer 생성
  • repository에 save
  • CreateDeveloper의 Response 형식으로 return해주기 위해 CreateDeveloper.Response클래스에 fromEntity 함수 생성하기

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

        public  static Response fromEntity(Developer developer){
            return Response.builder()
                    .developerLevel(developer.getDeveloperLevel())
                    .developerSkillType(developer.getDeveloperSkillType())
                    .experienceYears(developer.getExperienceYears())
                    .memberId(developer.getMemberId())
                    .build();
        }
    }

-> Developer -> CreateDeveloper.Response 형식으로 바꿈

테스트

  • 포스트맨 사용해서 테스트
  • Request 형식으로 데이터를 보내주면 Response형식으로 반환

  • h2를 확인해보니 developer테이블이 생성되었고, create한 값이 정상적으로 insert되었다.

Exception 테스트

  • 개발자 레벨과 연차가 맞지 않을 때 Exception 발생

  • Id가 중복되는 값이 있을 때 Exception 발생

0개의 댓글