221203 - Validation, Spring, Lombok, null-safety

Cornchip·2022년 12월 2일
0

Today-I-Learned

목록 보기
4/28

목차
1. Validation
2. Data Binding
3. Spring Resource
4. SpEL
5. Null Safety
6. Lombok library
7. HTTP 스펙 기초



1. Validation

  • Validation이란?

    유효성 검증
    주로 사용자 또는 서버의 요청 내용에서 잘못된 내용이 있는지 확인하는 단계를 뜻함

  • Validation의 종류

    학문적으로 여러 세부적인 단계들이 있기도 하지만 실제로 개발자가 주로 챙겨야 하는 검증은 크게 두 종류로 나뉜다.

    1. 데이터 검증
    2. 비즈니스 검증
    1. 데이터 검증

      필수 데이터의 존재 유무
      문자열의 길이나 숫자형 데이터의 경우 값의 범위
      email, 신용카드 번호 등 특정 형식에 맞춘 데이터

    2. 비즈니스 검증

      서미스에 정책에 따라 데이터를 확인하여 검증
      예) 배달앱인 경우 배달 요청을 할 때 해당 주문건이 결제 완료 상태인지 확인 등
      경우에 따라 외부 API를 호출하거나 DB의 데이터까지 조회하여 검증하는 경우도 존재


1) Spring의 Validation

  • 스프링은 웹 레이어에 종속적이지 않은 방법으로 validation을 하려고 의도하고 있으며 주로 아래 두가지 방법을 활용하여 validation 진행(둘다 주로 데이터 검증)
  1. Java Bean Validation

    JavaBean 기반으로 간편하게 개별 데이터를 검증
    요즘에 가장 많이 활용되는 방법 중 하나.

    요청 dto에 annotation으로 명시 후 @Valid annotation을 해당 @RequestBody에 달게 되면, Java Bean Validation을 수행한 후 문제가 없을 때만 메서드 내부로 진입이 된다.
    검증 중 실패가 발생하면 MethodArgumentNotValidException발생

  2. Spring validator 인터페이스 구현을 통한 validation


2) Validation 수행 시 주의사항 및 패턴

  1. 주의사항
  • validation이 너무 여러 군데에 흩어져 있으면 테스트 및 유지보수성이 떨어짐
    • 중복된 검증: 정책 변경 시에 모든 중복 코드를 수정해야 함
    • 다른 검증: 여러 군데에서 다른 정책을 따르는 검증이 수행될 수 있음
  • 가능한 validation은 로직 초기에 수행 후 실패 시에는 exception을 던지는 편이 처리가 편리함
  1. 실무 활용 패턴
  • 요청 dto에서 Java Bean Validation으로 단순 데이터(유무, 범위, 형식 등)를 1차 검증
  • 로직 초기에 2차로 비즈니스 검증 수행 후 실패 시에는 Custom Exception(Error Code, ErrorMessage를 입력)해서 예외를 던지도록 하고 예외처리하여 응답 생성
  • Spring validator의 장단점
    • 장점: Java Bean Validation에 비해 조금 더 복잡한 검증이 가능
    • 단점:
      • Validation을 수행하는 코드를 찾기가 상대적으로 어렵다.
      • 완전히 데이터만 검증하는 것이 아니기 때문에 일부 비즈니스적인 검증이 들어가는 경우가 있음(이 경우 비즈니스 검증 로직이 여러 군데로 흩어지기 때문에 잘못된 검증을 수행할 가능성이 높아짐)

2. Data Binding

  • 사용자나 외부 서버의 요청 데이터를 특정 도메인 객체에 저장해서 우리 프로그램에 Request에 담아주는 것을 뜻한다.
  1. Converter

    T convert(S source)
    S(source)라는 타입을 받아서 T(Target)이라는 타입으로 변환해주는 interface
    Spring Bean으로 등록하면 자동으로 ConversionService에 등록시켜 주기 때문에 필요에 따라 자동으로 동작하게 된다.

  2. Formatter

    특정 객체와 String 간의 변환을 담당하는 interface
    Spring Bean으로 등록하면 자동으로 ConversionService에 등록시켜 주기 때문에 필요에 따라 자동으로 동작하게 된다.



3. Spring Resource

  • java.net.URL의 한계(classpath내부 접근이나 상대경로)를 넘어서기 위해 스프링에서 추가로 구현
  • 업무에서는 많이 사용되지 않지만, 스프링의 내부 동작을 이해하기 위해 필요한 부분

1) Resource Interface와 그 구현체들

  • Resource 구현체 목록
    1. UrlResource

      java.net.URL을 래핑한 버전, 다양한 종류의 Resource에 접근가능하지만 기본적으로는 http(s)로 원격 접근


  1. ClassPathResource

    classpath 하위의 리소스 접근 시 사용


  1. FileSystemResource

    이름과 같이 File을 다루기 위한 리소스 구현체


  1. ServletContextResource, InputStreamResource, ByteArrayResource

    Servlet 어플리케이션 루트 하위 파일, InputStream, ByteArrayInput 스트림을 가져오기 위한 구현체


2) Spring ResourceLoader

  • 스프링 프로젝트 내 Resource에 접근할 때 사용하는 기능
  • 기본적으로 applicationContext에서 구현이 되어 있음
  • 프로젝트 내 파일에 접근할 일이 있을 경우 활용
  • 대부분의 사전정의된 파일들은 자동으로 로딩되도록 되어 있으나, 추가로 필요한 파일이 있을 때 이 부분 활용 가능

3) ResourcePatternResolver

  • 스프링 ApplicationContext에서 ResourceLoader를 불러올 때 사용하는 Interface
  • 위치 지정자 패턴("classpath:***", "file:***", ...)에 따라 자동으로 Resource 로더 구현체를 선택


4. SpEL

  • Expression Language는 짧고 간단한 문법을 통해 필요한 데이터나 설정 값을 얻어올 수 있게 하는 특별한 형태의 표현식에 가까운 간편한 언어(그래프 접근 등 가능)
  • SpEL은 그 중에서도 스프링 모든 영역에서 사용 가능한 언어형식

    주로 @Value("${config.value}")와 같은 방식으로 설정값을 주입받는 데에 사용


  1. SpEl의 값 평가(evaluation)
  2. Bean의 Property를 설정할 때 사용하는 방식


5. Null Safety

  • null 안정성을 높이는 방법
  • null 체크를 하지 않아서 발생하는 NPE(NullPointerException)을 방지하는 방법
  • IDE에서 경고를 표시하고 정확한 에러 위치를 확인할 수 있도록 도움

1) @NonNull Annotation

  • 해당 값이나 함수 등이 Null이 아님을 나타내는 어노테이션
  • org.springframework.lang.NonNull 사용
  • 메서드 파라미터에 붙이는 경우: null이라는 데이터가 들어오는 것을 사전에 방지함
  • 프로퍼티에 붙이는 경우: null을 저장하는 경우 경고
  • 메서드에 붙이는 경우: null을 리턴하는 경우 경고, 응답값을 저장하거나 활용하는 쪽도 NonNull이라고 신뢰하고 사용

2) @Nullable Annotation

  • @NonNull과 반대로 해당 데이터가 null일 수 있음을 명시함
  • 해당 annotation이 붙은 값을 사용하는 경우 null check를 항상 수행하도록 경고


6. Lombok library

  • @Builder: @Setter 와 비슷한 기능이다.

    dto.builder().fieldName($$).fieldName2(&&).build();
    의 형식으로 사용한다.

    코드의 응집력을 위해 사용한다.

  • @Slf4j: logging을 위해 사용한다.

  • @UtilityClass: 다양한 메서드들을 지원해주는 Utility Class를 만들 때 사용한다.

    해당 클래스를 final 클래스로 만든다.
    해당 클래스를 더 이상 상속받지 못하도록 만든다.
    생성자를 private로 만든다.



7. HTTP 스펙 기초

  1. HTTP Request 메시지 스펙
  • 첫째줄: 요청라인(HTTP 메서드(GET, PUT, POST) 등)
  • 두번째줄부터 줄바꿈 나오기 전까지: Header(User-Agent, Accept 등)
  • 헤더부터 줄바꿈 이후: Request Body
  1. HTTP Response 메시지 스펙
  • 첫째줄: 상태라인(200, 500 등)
  • 둘째줄부터 줄바꿈 전까지: Header
  • 헤더에서 줄바꿈 이후: Response Body
profile
cornchip

0개의 댓글