Programming/SpringBoot

SpringBoot의 HTTP Method API 정리

MJHmong 2023. 2. 22. 00:30

SpringBoot를 이용하면 어노테이션 기반으로 HTTP Method API를 구현할 수 있다.

어노테이션을 이용하여 간단하게 API 서버를 설계하며 사용법에 대해 간단히 알아보자.

 

개발환경에 대한 설정은 https://uosjihwan.tistory.com/93 를 참고하자.

 

우선 API를 구현하기 전에  @ResponseBody / @RestController 어노테이션에 대해 알아보자.

 

@ResponseBody

자바 객체를 HTTP Response의 Body부분에 매핑할 때 사용한다.

주로 자바의 객체를 HTTP Response의 Body 부분에 Json 형태로 매핑하여 전달할 때 사용한다.

 

@RestController

클래스에 @RestController를 선언하면 해당 클래스의 HTTP 요청 관련 모든 메서드에는 자동으로 @ResponseBody 가 설정된다.

즉 웹 애플리케이션에서 API 기능을 담당하는 Controller를 설계할 때 클래스단위로 적용하여 간단하게 API 서버를 구현할 수 있다.

 

@GetMapping

컨트롤러에서 HTTP Get Method를 구현할 때 사용한다. 아래 예시를 통해 사용 방법에 대해 예시를 통해 알아보자.

package hello.springmvc.demo.controller;

import hello.springmvc.demo.dto.UserRequest;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@RestController
@RequestMapping("/api/get")
// @RequestMapping -> controller에서 전달받을 URI를 명시한다.
// 클래스 위에 선언될 경우 하위에 구현된 HTTP Method 관련 URI prefix로 일괄 지정된다.
public class GetApiController {


    @RequestMapping(path = "/any-method")
    // 만약 위와같이 HTTP method에 대해서 명시하지 않으면, GET POST PUT DELETE 등에 대해 모두 매핑되니 유의하자
    // 아래에 GetMethod만 Mapping한 예제가 존재하니 꼭 확인하자.
    public String anyMethod() {
        return "any!";
    }

    @RequestMapping(path = "/get-method", method = RequestMethod.GET)
    public String getMethod() {
        return "get!";
    }


    @GetMapping(path = "/path-variable/{name}")
    // URI 상 변화하는 부분은 @PathVariable 로 전달받을 수 있다.
    public String pathVariable(@PathVariable(name = "name") String pathName) {
        System.out.println("PathVariable : " + pathName);
        return pathName;
    }


    @GetMapping(path = "/query-param")
    // http://localhost:9090/api/get/query-param?user=steve&email=steve@gmail.com&age=20
    // ?key1=value1&key2=value2 형식의 queryParam 형식은 @RequestParam 어노테이션 + Map 형태로 전달받을 수 있다.
    public String queryParam(@RequestParam Map<String, String> queryParam) {
        StringBuilder sb = new StringBuilder();
        queryParam.entrySet().forEach(entry -> {
            System.out.println(entry.getKey() + " : " + entry.getValue());
            sb.append(entry.getKey() + " : " + entry.getValue() + "\n");
        });
        return sb.toString();
    }

    // http://localhost:9090/api/get/query-param02?user=steve&email=steve@gmail.com&age=20
    @GetMapping(path = "/query-param02")
    // @RequestParam 을 각 Param 별로 지정하여 전달받을 수도 있다.
    public String queryParam02(
            @RequestParam String user,
            @RequestParam String email,
            @RequestParam int age) {

        return user + " " + email + " " + age;
    }


    @GetMapping(path = "/query-param03")
    // http://localhost:9090/api/get/query-param02?user=steve&email=steve@gmail.com&age=20
    // 가장 선호하는 방법으로 Request에 해당하는 클래스를 모델링하여 객체에 바로 매핑할 수 있다.
    public String queryParam03(UserRequest userRequest) {
        System.out.println(userRequest);
        return userRequest.toString();
    }
}

 

@PostMapping

컨트롤러에서 HTTP Post Method를 구현할 때 사용한다. 아래의 예시를 통해 다양한 사용법에 대해 익혀보자.

package hello.springmvc.demo.controller;

import hello.springmvc.demo.dto.PostRequestDto;
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("/api")
public class PostApiController {
    /**
     Post메소드로 요청오는 Request는 Data를 httpBody를 통해 데이터를 전달받으므로 RequestBody를 반드시 명시해주자.
     requestBody 예시.. Content-Type : application/json
     Body : 
      {
        "account":"user01",
        "email":"steve@gmail.com",
        "address":"fastcampus",
        "password":"abcd",
        "phone_number" : "010-9999-9999" -> 인식 못함..
      @JsonProperty("phone_number")를 DTO에 설정할 수 있음.
      }
     * **/
    @PostMapping(path = "/post")
    public void post(@RequestBody PostRequestDto requestDto) {
        // 위와 같이 @RequestBody가 명시된 경우 ( 원래 Post는 RequestBody로 데이터를 전달받긴 합니다.. )
        // Dto가 잘 설계 되어있다면 위에 명시된 Dto로 바로 파싱된다.
        System.out.println(requestDto);
    }
}

 

@PutMapping

위와 비슷하게 HTTP Put Method를 구현할 때 사용한다.

추가로 HTTP Request에는 car_number . RequestDto에는  carNumber로 다른 표기법으로 명시된 경우 @JsonNaming 어노테이션을 통해 둘 간의 표기법을 호환되게 설정할 수 있다.

package hello.springmvc.demo.controller;


import hello.springmvc.demo.dto.PutRequestDto;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
public class PutApiController {

    /**
     {
     "name" : "steve",
     "age" : 20,
     "car_list" : [
         {
         "name" : "bmw",
         "car_number" : "11가 1234"
         },
         {
         "name" : "A4",
         "car_number" : "22가 3456"
         }
       ]
     }

     //snake -> camel 자동 인식하는방법 -> @JsonNaming
     * **/

    @PutMapping("/put")
    // RequestBody는 변수가 camelCase , 실제 Request에는 snake_case로 표기되어있을때는 @JsonNaming을 Dto에 사용한다.
    public PutRequestDto put(@RequestBody PutRequestDto requestDto){
        System.out.println(requestDto);
        return requestDto;
    }

    @PutMapping("/put/{userId}")
    public PutRequestDto put(@RequestBody PutRequestDto requestDto, @PathVariable(name = "userId") Long userId){
        System.out.println(userId);
        System.out.println(requestDto);
        return requestDto;
    }
}
package hello.springmvc.demo.dto;

import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;

import java.util.List;

@JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class)
public class PutRequestDto {

    private String name;
    private int age;
    private List<Car> carList;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public List<Car> getCarList() {
        return carList;
    }

    public void setCarList(List<Car> carList) {
        this.carList = carList;
    }

    @Override
    public String toString() {
        return "PutRequestDto{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", carList=" + carList +
                '}';
    }
}

 

Response 에 대한 표준

여태까지 다양한 형태로 response를 반환하는 법에 대해 학습했다.

그러면 이제 가장 표준적으로 사용되는 Response 객체인 ResponseEntity 대해 예제로 알아보자.

package hello.springmvc.demo.controller;

import hello.springmvc.demo.dto.User;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
public class ApiController {

    @PutMapping("/response/put")
    public ResponseEntity<User> responsePut(@RequestBody User user){
        // Response return 시 가장 좋은 방법은 ResponseEntity 객체를 사용하는 것이다.
        // ResponseEntity 객체에는 Status Code 등의 추가적인 정보를 담아서 Client에 반환하는것이 가능하다.
        return ResponseEntity.status(HttpStatus.CREATED).body(user);
    }

}