ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 1. 스프링 Validation - 가장 기본뼈대
    스프링개발자/203 - Validation 2020. 8. 9. 10:50

    [배경]

    Client Request가 잘못된 경우에, 서버는 4XX 에러를 리턴한다.

    잘못된 Request의 정의는, 어플리케이션마다 다르지만, 흔히 다음과 같은 패턴을 갖는다

     

    • Request에 입력되야 할 필드값이 없다
    • Request에 입력되지 말아야 할 필드값이 있다
    • Request의 특정 Field의 값이 한계치보다 크다

    javax.validation.constraints 패키지에 있는 스프링 Validation은 몇가지 어노테이션만으로 스프링 Validation을 쉽게 구현할 수 있게 도와준다.


    1. Dispatch Request를 만들자

    최대한 간편하게 뼈대만 만든다.

     

    여기의 Business usage case는 다음과 같다.

    미국 월마트에서 Grocery를 배달해준다. 전날 미리 주문을 받아서, 차량의 route을 최적화 시켜준다.

    몇대의 배달자동차가 어떤 경로로 배달을 해야 최소거리 혹은 가장빨리 배달을 완수 하는지 계산해주는 서비스이다. (다소 복잡하지만, 앞으로 계속 쓰게될 문맥이다)

     

    package me.ndPrince.routeOptimization.model;
    
    import lombok.Data;
    
    import java.util.List;
    
    @Data
    public class DispatchRequest {
    
        protected List<RideRequest> rides;
        protected List<VehicleRequest> vehicles;
    }
    
    package me.ndPrince.routeOptimization.model;
    
    public class RideRequest {
    }
    
    package me.ndPrince.routeOptimization.model;
    
    public class VehicleRequest {
    }

    2. Dispatch Response를 만들자

    package me.ndPrince.routeOptimization.model;
    
    import lombok.Data;
    
    import java.util.List;
    
    @Data
    public class DispatchResponse {
    
        private List<VehicleScheduleResponse> vehicleSchedules;
    }
    
    package me.ndPrince.routeOptimization.model;
    
    public class VehicleScheduleResponse {
    }
    

    3. Dispatch Controller를 만들자

    package me.ndPrince.routeOptimization;
    
    import me.ndPrince.routeOptimization.model.DispatchRequest;
    import me.ndPrince.routeOptimization.model.DispatchResponse;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping(value = "/dispatch")
    public class DispatchController {
    
        @PostMapping
        public DispatchResponse postDispatchRequest(@RequestBody DispatchRequest request){
            return new DispatchResponse();
        }
    }
    

    4. Postman으로 다음을 테스트해본다

    Empty Dispatch를 넣었을때에, 200 response로 성공적으로 dispatch response결과값을 얻었다.

    5. 스프링 Validation 의존성을 추가하자

    // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-validation
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-validation', version: '2.3.1.RELEASE'
    

    6. Dispatch Request에 Validation 을 추가하자

    package me.ndPrince.routeOptimization.model;
    
    import lombok.Data;
    
    import javax.validation.constraints.NotNull;
    import java.util.List;
    
    @Data
    public class DispatchRequest {
    
        @NotNull
        protected List<RideRequest> rides;
        protected List<VehicleRequest> vehicles;
    }
    

     @NotNull 이라는 어노테이션을 추가했다. javax 패키지에서 제공되는 어노테이션을 써야한다.

    4번의 postman post request를 실행해보면, rides를 제공하지 않았음(Null)에도 여전히 200 결과값이 나온다.

    스프링 Validation은 @Valid와 함께 실행될때 효과가 발휘된다.

    package me.ndPrince.routeOptimization;
    
    import me.ndPrince.routeOptimization.model.DispatchRequest;
    import me.ndPrince.routeOptimization.model.DispatchResponse;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.validation.Valid;
    
    @RestController
    @RequestMapping(value = "/dispatch")
    public class DispatchController {
    
        @PostMapping
        public DispatchResponse postDispatchRequest(@Valid @RequestBody DispatchRequest request){
            return new DispatchResponse();
        }
    }
    

     7. Postman으로 (4)를 반복

    다음과 같은 400 response를 볼 수 있다

    rides값을 제공해보면 200 response를 볼 수 있다;

    Empty list와 Null 값은 분명히 다르다.

    Null은 아무것도 제공하지 않은 값이고, Empty list는 size가 0인 값을 제공했을 뿐이다.

    "rides": [] 는 empty이지, null은 아니다.

    8. 여러가지 스프링 Validation을 연습하자

    @Valid

    @NotNull

    @Size(min =1, max = 100)

    @NotEmpty

    @Min @Max

    @Email

    등등..

     

    9. 보너스 Github (본 포스팅에 사용된 git관련 흔적)

    git status
    git checkout -b spring_validation_1
    git add .
    git commit -m "completed"
    git push --set-upstream origin spring_validation_1

    git repo에서 PR를 만들자 - 동료들로부터 code review를 받을 수 있다.

    본 포스팅에 사용된 branch

    https://github.com/2ndPrince/routeOptimization/tree/spring_validation_1

Designed by Tistory.