스프링 1-4. POST API
1. 개요
POST의 특징은
- 리소스 생성, 추가용
- CRUD의 C
- 생성, 추가용이니 멱등하지 않다. (원래 3번째였는데 새로운 거 하나 생기면 4번째가 됨)
- 안정성도 없다 (새로 생성이나 추가니 안정성이 있다고 보긴 힘들다)
- PathVariable 사용이 가능하다.
- Query Parameter는 쓸 순 있는데 별로 안 씀
- DataBody를 주로 쓴다.
주로 데이터를 DataBody에 실어서 보낸다. 원래는 xml 방식도 썼는데 요즘은 거의 json 형태로 보냄
2. 사용법
2-1. Json 데이터
Json데이터는
String : value, number : value, Boolean = value, object = value { }, array = value []형태의 데이터를 받는다.
{
“key”: “value”
}
이런 매핑변수 형태다.
{
“id” : “010-1111-2222”,
“age” : 10,
“isAgree” : false,
“account” : { // object 형태
“email” : steve@gmail.com,
“password” : “1234”
}
}
// user 조회하는 경우
{
“account” : “abcd”,
“password” : “1234”
} // 이런 것들이 배열로 들어감
{
“user_list” : [
{
“account” : “abcd”,
“password” : “1234”
},
{
“account” : “aaaaa”,
“password” : “1111”
},
{
“account” : “dsa”,
“password” : “5555”
}
]
}
Json을 사용할 때, 규칙은 스네이크 케이스와 카멜 케이스가 있다.
카멜 : phoneNumber, eMail
스네이크 : phone_number, e_mail
보통 json에선 스네이크 케이스를 많이 쓰는데 자바에선 거의 카멜 케이스를 사용한다.
아무튼 json으로 서버에 요청을 할 때는
DataBody에
{
“account” : “”,
“email” : “”,
“password” : “”,
“address” : “”
}
형태로 데이터를 실으면 된다.
2-2. Post
서버에서 처리하는 방법은
@RestController
@RequestMapping
public class PostApiController {
@PostMapping("/post")
public void post(Map<String, Object> requestData) {
requestData.entrySet().forEach(stringObjectEntry -> {
System.out.println("key : "+stringObjectEntry.getKey());
System.out.println("value : "+stringObjectEntry.getValue());
});
}
}
Map으로 받아서 entrySet으로 처리할 수 있는데 forEach 부분에서 option+enter 를 치면 더 간결하게
만들 수 있다.
@PostMapping("/post")
public void post(Map<String, Object> requestData){
requestData.forEach((key,value)->{
System.out.println("key : "+key);
System.out.println("value : "+value);
});
}
그런데 Post방식의 정석은 RequestBody에 데이터를 넣는 방식이다.
@PostMapping("/post")
public void post(@RequestBody Map<String, Object> requestData) {
requestData.forEach((key, value) -> {
System.out.println("key : " + key);
System.out.println("value : " + value);
});
}
그리고 여기서도 dto를 활용할 수 있다.
package com.example.post.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
public class PostRequestDto {
private String account;
private String email;
private String address;
private String password;
@JsonProperty("phone_number")
private String phoneNumber;
@JsonProperty("OTP")
private String OTP;
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "PostRequestDto{" +
"account='" + account + '\'' +
", email='" + email + '\'' +
", address='" + address + '\'' +
", password='" + password + '\'' +
'}';
}
}
하나씩 설명하면 아까 설명했듯이 자바에선 주로 카멜 케이스, Json에선 주로 스네이크 케이스를 쓴다.
클라이언트가 스네이크 케이스로 데이터를 보내면, 카멜 케이스로 선언된 dto에서 처리하질 못한다.
그래서 나온 게 @JsonProperty 이다. 파라미터로 들어온 ("phone_number")와 변수 명인 phoneNumber
뭐가 들어오든 처리할 수 있게 하는 것이다.
그리고 OTP처럼 카멜도 스네이크도 아닌 경우, Property를 붙여주는 게 편하다.
@RestController
@RequestMapping("/api")
public class PostApiController {
@PostMapping("/post")
public void post(@RequestBody PostRequestDto requestData) {
System.out.println(requestData);
}
}
dto 객체를 @RequestBody 에 실어서 처리하면 된다. 결과는 toString과 같이 나온다.
만약 데이터를 처리하고 싶으면 requestData.get메소드 를 사용하면 된다.
2-4. 어노테이션 정리
마지막으로 어노테이션을 정리하고 가면
@RestController : Rest API 설정
@RequestMapping : 리소스를 설정 (method로 구분 가능)
@PostMapping : Post Resource 설정
@RequestBody : Request Body 부분 Parsing
@PathVariable : URL Path Variable Parsing
@JsonProperty : json naming
@JsonNaming : class json naming // 클래스 전체 설정