스프링

스프링 1-4. POST API

호놀롤루 2022. 3. 15. 15:49

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 // 클래스 전체 설정