Springboot REST API 구현하는 방법, POST Method 구현 (@PostMapping, @RestController)
오늘은 HTTP 의 "POST" 기능을 Springboot 로 구현하는 예제를 작성해보려고한다.
📌HTTP "POST" 란?
GET 방식과는 달리, POST 기능에서는 body 영역에 데이터를 실어 보낼 수 있다. GET 방식 또한, 데이터 전달은 가능하지만, body 영역을 사용할 수 없다는 차이점이 있으며, 실어보낼 수 있는 데이터의 양또한 차이가 있다.
POST 기능을 구현할 때 사용한 어노테이션 (Annotation) 리스트는 무엇이 있을까?
"@RequestController" : 아래 선언된 클래스를 Rest API Controller 로 사용하겠다라는 의미
"@RequestMapping" : 해당 컨트롤러에 접근하기위한 URI 맵핑
"@PostMapping("/post") : 컨트롤러 내에 있는 Method 접근을 위한 URI 맵핑
"@RequestBody Map<String, String> reqData" : Post 요청 시 전달되는 Body 값을 전달받을 입력 파라미터
"POST" 기능 구현을 위한 Controller Class를 생성 해주는데, 나는 이름을 "PostController" 로 작성했다.
이후 Class 선언 위쪽에 어노테이션(Annotation) 으로 REST API Controller로 사용하겠다 지정을해준다.
"@RestController"
이제 해당 클래스와 URI Mapping 을 해줄건데, 해당 클래스에 서비스를 사용하기 위한 URI 는 "/test/post" 로 정했다.
"@RequestMapping(path="/test/post")"
@RestController
@RequestMapping(path="/test/post")
public class PostController {
}
}
POST 기능을 사용할 때 GET 방식과의 차이점은 body 영역을 사용한다고 했는데,
body 영역에는 다양한 데이터 포맷을 보낼 수 있다. 예를 들면, 파일, 이미지, html, text, byte array 등 다양하다.
오늘 구현하는 예제에서는 보내고 싶은 데이터를 JSON 형식의 텍스트 파일로 만들어서 보낸다.
먼저! JSON 이란 무엇일까?
📌JSON (JavaScript Object Notation) 이란?
속성-값 쌍(attribute-value pairs), 배열 자료형(array data types) 또는 기타 모든 시리얼화 가능한 값 또는 "키-값" 쌍으로 이루어진 데이터 오브젝트를 전달하기 위해 인간이 읽을 수 있는 텍스트를 사용하는 개방형 표준 포맷이다.
단순하게, Server 와 Client 간에 데이터를 주고받을 때, Text 형식에서의 특정한 포맷이라고 생각하면된다.
물론 xml, javascript 등 다양한 형식으로 보낼 수 잇다.
JSON으로 선정한 이유는,
WEB 개발 시 많이 사용하게 되는 데이터 규격이기도하고, 임베디드 개발할 때도 유용하게 사용된다.
JSON 포맷의 간단한 예시를 보면 아래와 같다.
{
"userName" : "john-co",
"phoneNumber" : "010-1234-5678",
"acceptCount" : 10,
"account" : {
"id" : "001003"
"address" : "john-co@tistory.com",
"passward" : "1234"
},
"like" : ["game","programming","money"]
}
위 예시는, 일반 Value 값을 "String", "int", "object", "array" 등을 표현했다.
"String" 을 값으로 하는 Key는 "userName", "phoneNumber" 가 있고,
"int" 를 값으로 하는 key는 "acceptCount" 가 있으며,
"object" 를 값으로 하는 key 는 "account",
"array" 를 값으로 하는 key 는 "like" 가 있다.
물론 "array" 타입으로 보낼 때, object를 array 형식으로 보낼수도 있다.
REST API 개발 시에는 특정한 약속이 있는데, JSON 데이터 형식의 Key 이름을 정할 때에도 약속이 있다.
크게 Camel Case, Snake Case 등이 있는데, 이 2종류가 무엇인지 간단히 정리하자면,
Camel Case 로 Naming 을 한다면, "phoneNumber" 가되고,
Snake Case 로 Naming 을 한다면, "phone-number" 가 된다.
위 2개의 차이점을 보면,
Camel Case 는 단어가 바뀔 때 대문자를 쓰는데, 이때 볼록 튀어나온 부분이 낙타와 비슷하다는 의미고,
Snake Case 는 중간에 "-" (대시) 로 쭉 이어져서 뱀과 비슷하다는 의미다.
나는 위에서 "Camel Case"로 작성했고, 해당 예시는 "userName", "phoneNumber", "accpetCount" 가 있다.
이제 Spring boot로 POST 기능을 구현해서, talend api tool 로 예제를 테스트해보자.
POST 요청 시 받을 위 JSON 데이터를 기준으로, DTO 클래스를 만들어 볼건데,
일단은 "account" 라는 object 를 받기위해, 이 account 를 담을 Class 먼저 만들고,
전체 JSON을 담기위한 Class 를 생성한다.
일단 "account" object 를 담을 "AccountDto" 클래스를 생성하고, 내용을 작성한다.
package com.example.httpapi.http.post.dto;
public class AccountDto {
private String id;
private String address;
private String password;
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;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public String toString() {
return "AccountDto{" +
"id='" + id + '\'' +
", address='" + address + '\'' +
", password='" + password + '\'' +
'}';
}
}
이제 전체적인 JSON 데이터를 담기위한 DTO Class 인, "PostRequestDto" 클래스를 생성하고, 내용을 작성한다.
package com.example.httpapi.http.post.dto;
import java.util.List;
public class PostRequestDto {
private String userName;
private String phoneNumber;
private int acceptCount;
private AccountDto account;
private List<String> like;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public int getAcceptCount() {
return acceptCount;
}
public void setAcceptCount(int acceptCount) {
this.acceptCount = acceptCount;
}
public List<String> getLike() {
return like;
}
public void setLike(List<String> like) {
this.like = like;
}
public AccountDto getAccount() {
return account;
}
public void setAccount(AccountDto account) {
this.account = account;
}
@Override
public String toString() {
return "PostRequestDto{" +
"userName='" + userName + '\'' +
", phoneNumber='" + phoneNumber + '\'' +
", acceptCount=" + acceptCount +
", account=" + account +
", like=" + like +
'}';
}
}
위 코드에서 변수 이외에도 여러 Method가 선언되어 있는데,
DTO 구현에서 필수적으로 생성되어야 할 Method 는 Getter, Setter 다.
Getter, Setter 가 구현되어 있어야, ObjectMapper 가 정상적으로 동작할 수 있다.
Getter 와 Setter 이름을 임의로 변경하면 ObjectMapper가 정상적으로 동작하지 않으니 주의한다!
이제 PostController에서 JSON 데이터를 보냈을 때 이를 처리하는 Method를 작성한다.
Method 명은 "PostJsonData" 로 하고, URI Mapping은 "/json" 으로 했다.
"@PostMapping("/json")
또한, POST 요청에서는 body 영역을 사용할 수 있다고 했는데,
이 body 영역에 데이터를 받을 Input parameter 지정을 하는데 이렇게 만들어진 함수의 원형은,
"public void PostJsonData(@RequestBody PostRequestDto postRequestDtO)" 가 된다.
위 내용을 종합해서 PostJsonData 기능을 구현한다.
@RestController
@RequestMapping("/test/post")
public class PostController {
@PostMapping("/json")
public void PostJsonData(@RequestBody PostRequestDto postRequestDto){
System.out.println(postRequestDto.toString());
}
}
단순히 POST 요청을 받고, body 영역의 데이터를 출력해주는 기능이다.
이를 실행하고, Talend 에서 테스트를 진행해보면,
METHOD 에서 "POST" 를 선택하고, 주소를 입력한 후,
JSON 데이터를 입력하고 "Send" 버튼을 클릭하면 아래와 같은 결과를 얻을 수 있다.
[참고]
JSON - 위키백과, 우리 모두의 백과사전
위키백과, 우리 모두의 백과사전. JSON(제이슨[1], JavaScript Object Notation)은 속성-값 쌍(attribute–value pairs), 배열 자료형(array data types) 또는 기타 모든 시리얼화 가능한 값(serializable value) 또는 "키-값
ko.wikipedia.org