[데브코스] Spring Rest API 2

Updated: Categories:

W5D4 - 렌더링방식 / ResponseEntity / CORS에 대해 알아보자!

렌더링 방식

image

MPA (Multiple Page Application)

  • 여러개의 페이지로 구성된 APP. 전통적인 방식
  • SSR(Server Side Rendering) 방식으로 렌더링
  • 사용자 데이터는 서버에서 세션으로 처리
  • 하나의 URL에 하나의 페이지를 매핑

SPA (Single Page Application)

  • 한 개의 페이지로 구성된 APP
  • CSR(Client Side Rendering) 방식으로 렌더링함
  • 사용자 데이터는 브라우저의 local storage를 함께 활용해 세션 의존도를 줄임
  • 히스토리 API + DOM 조작을 통해 새로고침 없이 렌더링

Proxy

  • if) React에서 프론트를 서빙하는 웹서버가 있다 (3000번 포트로)
  • 만약 프론트 부분에 백엔드로 요청을 보내는 코드를 작성하게 되면 CORS 에러 발생
  • 프론트 코드에서 해당 주소를 웹서버로 넘기고 웹서버가 백엔드 서버로 요청해야함 (프록시 적용)


ResponseEntity

  • HTTP의 헤더나 상태코드를 처리하기 위한 자료형
  • 응답 컨트롤러의 리턴값으로 주고 다양한 메소드를 통해 HTTP 타입을 표현 가능
@GetMapping(".../{데이터}")
@ResponseBody
public ResponseEntity<제네릭> 메소드(@PathVariable(데이터) ...) {
  ResponseEntity.ok(...);
  ResponseEntity.status(...).body(...);
  ResponseEntity.notFound().build();
}


CORS (Cross Origin Resource Sharing)

  • 동일한 출처의 리소스에만 접근이 가능하도록 하는 규칙
  • 프로토콜, 호스트, 포트가 동일하면 Same Origin으로 본다.
  • 이 블로그에 매우 자세한 설명이 나와있음

단순요청

image

  • GET, HEAD, POST 메소드 요청
  • 유저 에이전트가 자동으로 설정한 헤더
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type
  • Content-Type 헤더는 아래 값들만 허용
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

예비요청 (Preflight)

image

  • 단순 요청이 아닌경우엔 예비요청을 먼저 보낸다
  • 서버가 예비요청을 받고 Access-Control-Allow-Origin 헤더를 포함한 응답을 브라우저로 보내줘야 비로소 본 요청이 이루어짐.
  • 서버가 요청에 승인을 해주는 것이므로 서버측에서 CORS 모듈을 사용한다


Spring CORS

CORS 설정 - Servlet Context

  • Servlet Context Config에서 addCorsMappings 메소드를 사용해 CORS 허용을 해줄 수 있다.
  • 허용할 Origin, URL, 메소드를 정할 수 있음
@Override
public void addCorsMappings(CorsRegistry registry) {
    // api/ 하위로 들어오는 모든 origin의 GET 요청만 허용한다
    registry.addMapping("/api/**")
            .allowedMethods("GET")
            .allowedOrigins("*");
}

CORS 설정 - Annotation

  • 컨트롤러 클래스나 포함 메소드에 @CrossOrigin 달아 기능별로 설정도 가능함
@CrossOrigin(origins=" ", methods = RequestMethod.GET)
[ 컨트롤러 or 메소드 ]


DTO

  • Request가 오면 메시지 컨버터로 도메인에 맞는 형식으로 변환하여 파라미터로 받을 수 있다.
  • 이때 도메인 형식을 정의해주는 것이 바로 DTO인데 보통 Record 클래스로 작성한다
    • 도메인을 수정하지 않고 DTO를 만들어주는 것이 좋음
  • Request -> 메시지컨버터(@RequestBody) -> DTO -> 사용
Request를 DTO로 변환 후 응답하는 메소드
@PostMapping(".../{데이터}}")
@ResponseBody
public 메소드(@PathVariable("데이터") ..., @RequestBody DTO dto) {
  dto.value();
  ...
}
DTO - Record 클래스 정의
public record DTO(
        Value value,
        ...
) {
    // value -> dto
    static DTO of(Value value) {
        return new CustomerDto(
                value.getValue(),
                ...
        );
    }

    // dto -> customer
    // 생성의 책임이 service에 있을지 dto에 있을지는 고민
    static Value to(DTO dto) {
        return new Customer(
                dto.value(),
                ...
        );
    }
}