지난 GET API에 대해 공부한 것에 이어 오늘은 POST API에 대해 공부해보고자 한다.
먼저 POST API의 특징에 대해 알아보자
@RestController
@RequestMapping("/api")
public class PostApiController {
@PostMapping("/post")
public void post(@RequestBody Map<String, Object> requestData){
requestData.forEach((key, value) -> {
System.out.println("key : " + key);
System.out.println("value : " + value);
});
}
}
POST API도 GET API과 같이 parameter앞에 무언가를 붙여줘야한다. Get은 데이터를 읽어오기 위해 clinet에서 읽어오고자 하는 data의 parameter를 보내고 Server는 그것을 받기 위해 @RequestParam을 붙였다면 POST는 데이터를 생성하고 추가하기 위해 아래 사진과 같이 Json 또는 XML타입의 데이터를 Client에서 보내기 때문에 Post는 Data block을 받기 위해 @RequestBody를 붙여준다.
@RestController
@RequestMapping("/api")
public class PostApiController {
@PostMapping("/post1")
public void post1(@RequestBody PostRequestDTO requestData){
// get과 다르게 객체를 사용하여 받아와도 RequestBody를 입력해줘야한다.
System.out.println(requestData);
}
}
POST API도 Map형식 말고 DTO(class)를 통해 POST가 가능하다.
POST에서 객체를 사용하여 데이터를 받아올 때는 GET과 다르게 method parameter앞에 @RequestBody를 붙여줘야한다.
단어 표현은 Snake case와 Camel Case를 가장 많이 사용한다.
Snake case는 단어의 구분을 _(언더바)를 사용하여 구분하여 snake_case와 같이 표현을 하는 방법이다.
Camel case는 단어의 구분을 단어의 시작을 대문자로 만들어 구분을 하는 방법으로 camelCase와 같이 대문자로 구분을 하는 방법이다.
우리가 공부할 JSON과 spring boot의 Java는 대표적으로 사용하는 표현법이 서로 다르다. JSON의 경우는 Snake case를 주로 사용하며 Java에서는 Camel case를 주로 사용한다.
우리는 데이터를 원활하게 읽어오도록 구현하기 위해서는 snake case뿐만 아니라 camel case로도 parsing이 가능하도록 구현을 해야한다.
Spring boot에서는 @JsonProperty, @JsonNaming를 사용하면 쉽게 해결할 수 있다.
PostRequestDTO.java
public class PostRequestDTO {
private String account;
private String email;
private String address;
private String password;
private String phoneNumber;
.....
}
Request에 보내는 JSON
{
"account" : "user01",
"email" : "abc123@gmail.com",
"address" : "Korea",
"password" : "adcd",
"phone_number" : "010-1234-5678"
}
class내의 phoneNumber는 camel case로 생성되었다 하지만 request body에 담겨 보내지는 json에서는 phone_number와 같이 snake case로 key값이 정의되었다.
이러한 경우 request를 한다면 전화번호는 아래와 같이 null값이 출력될 것이다.
Result
PostRequestDTO{account='user01', email='abc123@gmail.com', address='Korea', password='adcd', phoneNumber='null'}
해결법 중 하나는 @JsonProperty을 이용해 다른 이름도 허용되도록 하는 것이다.
@JsonProperty는 OTP와 같이 camel도 아니고 snake도 아닌 애매한 것들은 JsonProperty("OTP")와 같은 것을 붙여 matching을 시켜주기도 한다.
public class PostRequestDTO {
private String account;
private String email;
private String address;
private String password;
@JsonProperty("phone_number")
private String phoneNumber;
.....
}
이와 같이 JsonProperty annotation을 통해 phoneNumber를 phone_number도 허용하게 한다면 null이었던 phoneNumber값이 정상적으로 출력되는 것을 확인할 수 있다.
Result
PostRequestDTO{account='user01', email='abc123@gmail.com', address='Korea', password='adcd', phoneNumber='010-1234-5678'}
@JsonProperty는 변수 하나씩 지정해야하는 번거로움이 있다. @JsonNaming을 사용하면 class전체의 변수들을 camel case에서 snake case로 매칭시켜줄 수 있다.
@JsonNaming(value = PropertyNamingStrategy.SnakeCaseStrategy.class)
public class PostRequestDTO {
private String account;
private String email;
private String address;
private String password;
private String phoneNumber;
.....
}