2.2.4 컨트롤러 레이어 : 스프링 REST API 컨트롤러

jaehyeok1230·2022년 11월 26일
0

HTTP는 메서드와 URI를 이용해 서버에 HTTP요청을 보낼 수있다. 서버는 이 요청을 받은 후 어떻게 처리 해야 할까?


http GET 메서드를 이용해 test라는 리소스를 요청한다는 뜻이다. 따라서 서버는 자신의 주소를 제외한 /{리소스} 부분을 이해하고, 또 이 요청이 어떤 HTTP 메서드를 이용했는지 알아야 한다. 그 후 해당 리소스의 HTTP 메서드에 연결된 메서드를 실행해야 한다.

스프링 부트 스타터 웹의 어노테이션을 이용하면 이 연결을 쉽게 할 수 있다.

implementation 'org.springframework.boot:spring-boot-starter-web'

Test Controller

@RestController
@RequestMapping("test") //리소스
public class TestController {

	@GetMapping
    public String testController() {
        return "Hello world!";
    }
}

@RestController를 이용하면 http 관련된 코드 및 요청/응답 매핑을 스프링이 알아서 해준다.
@GetMapping 어노테이션을 이용해 이 메서드의 리소스와 HTTP 메서드를 지정한다. 클라이언트가 이 리소스에 대해 Get 메서드로 요청하면 @GetMapping에 연결된 컨트롤러가 실행된다.

빌드 실행

PostMan

매개변수를 넘겨받는 방법

만약 /test/{id}처럼 PathVariable 이나 /test?id=123 처럼 요청 매개변수를 받아야 한다면 어떻게 해야할까?

@PathVariable

@PathVariable을 이용하면 /{id}와 같이 URI의 경로로 넘어오는 값을 변수로 받아 올수 있다.

@GetMapping("/{id}")
    public String testControllerWithPathVariable(@PathVariable(required = false) int id)
    {
        return "Hello World! ID " + id;
    }
    //(requierd = false)은 이 매개변수가 꼭 필요한건 아니라는 뜻이다.

@RequestParam

@RequestParam을 이용하면 ?id={id}와 같이 요청 매개변수로 넘어오는 값을 변수로 받아올 수 있다.

//  /test 경로는 이미 존재하므로 /test/testRequestParam으로 지정했다.
    @GetMapping("/testRequestParam")
    public String testControllerRequestParam(@RequestParam(required = false) int id) {
        return "Hello World! ID " + id;
    }

@RequestBody

RequestBody는 보통 반환하고자 하는 리소스가 복잡할 때 사용한다. 기본 자료형이 아닌 오브젝트처럼 복잡한 자료형을 통째로 요청에 보내고 싶은 경우가 이에 해당한다.

package com.example.demo.dto;

import lombok.Data;

@Data
public class TestRequestBodyDTO {
    private int id;
    private String message;
}
//TestRequestBodyDTO 생성
// /test 경로는 이미 존재하므로 /test/testRequestBody로 지정했다.
    @GetMapping("/testRequestBody")
    public String testControllerRequestBody(@RequestBody TestRequestBodyDTO testRequestBodyDTO) {
        return "Hello world! ID " + testRequestBodyDTO.getId()
                + " Message : " + testRequestBodyDTO.getMessage();
    }
    //TestRequestBodyDTO를 요청 바디로 받는 testControllerRequestBody()메서드 생성

@RequestBody TestRequestBodyDTO testRequestBodyDTO는 RequestBody로 날아오는 JSON을 TestRequestBodyDTO 오브젝트로 변환해 가져오라는 뜻이다.

@ResponseBody

@RestController를 이루는 두개의 어노테이션중 하나는 @Controller고 다른 하나는@ReponseBody이다. @Controller를 더 들여다 보면 @Component로 스프링이 이 클래스의 오브젝트를 알아서 생성하고 다른 오브젝트들과의 의존성을 연결한다는 뜻이다.
@ResponseBody는 이 클래스의 메서드가 리턴하는 것은 웹 서비스의 ResponseBody라는 뜻이다. 메서드가 리턴할 때 스프링은 리턴된 오브젝트를 JSON의 형태로 바꾸고 HttpResponse에 담아 반환한다는 뜻이다.

  • 스프링이 오브젝트를 JSON으로 바꾸는 것처럼 오브젝트를 저장하거나 네트워크를 통해 전달할 수 있도록 변환하는 것을 Serialization(직렬화)이라고 하고 반대의 작업을 Deserialization(역직렬화)라고 한다.
@GetMapping("/testResponseBody")
    public ResponseDTO<String> testControllerResponseBody() {
        List<String> list = new ArrayList<>();
        list.add("Hello World! I`m ResponseDTO");
        ResponseDTO<String> response = ResponseDTO.<String>builder().data(list).build();
        return response;
    }

ResponseEntity

ResponseEntity는 HTTP 응답의 바디뿐만 아니라 여러 다른 매개변수들(status,header 등)을 조작하고 싶을 때 사용한다.

@GetMapping("/testResponseEntity")
    public ResponseEntity<?> testControllerResponseEntity() {
        List<String> list = new ArrayList<>();
        list.add("Hello World! I`m ResponseEntity. And you got 200!");
        ResponseDTO<String> response = ResponseDTO.<String>builder().data(list).build();
        //http status를 200으로 설정.
        return ResponseEntity.ok().body(response);
    }

ResponseDTO를 리턴하는 것과 비교했을 때 리턴된 Body는 아무 차이가 없다. 단지 헤더와 HTTP status를 조작할 수 있다는 점이 다르다.

0개의 댓글