SpringBoot의 HTTP Method API 정리
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);
}
}