스프링 부트 핵심 가이드 책을 보고 정리한 내용입니다.
POST API
POST API는 웹 애플리케이션을 통해 데이터베이스 등의 저장소에 리소스를 저장할 때 사용되는 API이다. 웹 API에서 HTTP POST 메서드를 사용하여 요청을 보내며 저장하고자 하는 리소스나 값을 HTTP 바디(body)에 담아 서버에 전달한다.
@RequestMapping으로 구현하기
@RequestMapping은 Spring Framework에서 HTTP 요청을 Java 메서드에 매핑하기 위해 사용되는 애노테이션이다.
만약 POST API를 정의하고자 한다면, 아래와 같이 정의할 수 있다.
@RequestMapping(value = "/myApi", method = RequestMethod.POST)
public String postMethod() {
// 여기에 로직을 추가합니다.
return "POST 요청이 성공적으로 처리되었습니다.";
}
method 요소의 RequestMethod.POST를 설정하여 사용한다.
그러나 요즘에는 @PostMapping 이라는 애노테이션이 제공되어, 이를 이용해 간결하게 표현한다. 쉽게 말해, @PostMapping 애노테이션은 @RequestMapping + POST method 의 조합이라고 생각하면 된다.
@RequestBody를 활용한 POST 메서드 구현
위에 예제에선 리소스를 받지 않고 단지 POST 요청을 확인하기 위한 메서드를 구현했다면 이번엔 리소스를 받아 처리하는 메서드를 구현해 보자.
일반적으로 POST API는 클라이언트가 서버에 리소스를 저장할 때 사용한다. 그러므로 클라이언트의 요청 트래픽에 값이 포함되어 있어야 한다. 이때 HTTP Body에 값을 넣어 전송한다. 그렇기 때문에 서버에서는 @RequestBody 애노테이션을 이용해 Body에 담겨있는 값을 받아야 한다.
아래 이미지는 Body 영역에 값을 입력하여 전송하는 예제이다. 예제를 살펴보면 Body 영역에 작성할 값은 일정한 형태를 갖춘 것을 알 수 있다. 이를 JSON 형태라고 하며 일반적으로 RESTful API은 JSON 형태의 데이터를 많이 사용한다. 기본적으로 Spring Boot에서 제공되는 messageconverter에 JSON을 사용하고 문자열 형태의 값을 전달하기 때문에 파싱의 이점이 있어 많이 사용된다.
Map을 활용한 @RequestBody 처리
Map 객체를 활용하는 방법은 주로 어떤 값이 들어올게 될지 특정하기 어려울 때 주로 사용한다.
@RequestMapping(value = "/member", method = RequestMethod.POST)
public String postMember(@RequestBody Map<String, Object> postData){
StringBuilder sb = new StringBuilder();
postData.entrySet().forEach(map -> {
sb.append(map.getKey() + " : " + map.getValue());
});
return sb.toString();
}
추가적으로 @RequestBody를 이용하면 HTTP 요청 본문(Body)의 내용을 지정된 객체로 바인딩할 수 있다.
DTO을 활용한 @RequestBody 처리
반대로 요청 메시지의 값이 정해져 있고, 받아야 할 파라미터 많은 경우는 DTO 객체를 사용한다.
package com.core.testproject.dto;
public class MemberDto {
private String name;
private String email;
private String organization;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getOrganization() {
return organization;
}
public void setOrganization(String organization) {
this.organization = organization;
}
@Override
public String toString() {
return "MemberDto{" +
"name='" + name + '\'' +
", email='" + email + '\'' +
", organization='" + organization + '\'' +
'}';
}
}
@PostMapping("/member2")
public String postMember2(@RequestBody MemberDto memberDto){
return memberDto.toString();
}
위와 같이 작성하면 MemberDto의 멤버 변수를 요청 메서지의 키와 매핑해 값을 가져온다. 주의할 점은 GetMapping에서는 @RequestBody를 붙이지 않아도 값이 정상적으로 들어오는데 PostMapping을 이용할 때는 @RequestBody 애노테이션을 붙여야지만 정상적으로 값을 받아올 수 있다.
PUT API
PUT API는 웹 애플리케이션 서버를 통해 데이터베이스 같은 저장소에 존재하는 리소스 값을 업데이트하는 데 사용된다.
서비스 로직 관점에서 POST랑 차이가 있지만 클래스를 구현하는 방법은 거의 동일하다. 리소스를 서버에 전달하기 위해 HTTP Body를 활용하기 때문이다.
POST API와 PUT API의 차이
POST API는 새로운 리소스를 생성하거나 기존 리소스의 데이터를 추가할 때 사용된다. 이것을 서비스 로직 관점에서 본다면 새로운 리소스가 서버에 제출되고, 서버는 해당 리소스를 기반하여 새로운 리소를 생성한다. 쉽게 말해서 POST는 같은 데이터를 여러 번 전송하면 동일한 데이터가 여러 번 생성될 수 있다. (멱등성이 없다고 표현한다.)
PUT API는 기존 리소스를 대체하거나, 해당 리소스가 존재하지 않으면 새로운 리소스로 생성한다. 서비스 로직 관점에서는 해당 리소스가 이미 존재하면 기존 데이터를 대체하고, 없으면 새로운 리소스를 생성한다. 그렇기 때문에 PUT은 같은 데이터를 여러 번 전송하더라도 결과는 항상 같다. (멱등성이 있다고 표현한다.)
PUT API는 POST API와 사용법을 거의 동일하기 때문에 예제 코드만 간단히 제공한다.
@PutMapping(value = "/member")
public String postMember(@RequestBody Map<String, Object> putData) {
StringBuilder sb = new StringBuilder();
putData.entrySet().forEach(map -> {
sb.append(map.getKey() + " : " + map.getValue() + "\n");
});
return sb.toString();
}
@PutMapping(value = "/member1")
public String postMemberDto1(@RequestBody MemberDto memberDto) {
return memberDto.toString();
}
DELETE API
DELETE API는 웹 애플리케이션 서버를 거쳐 데이터베이스 등의 저장소에 있는 리소스를 삭제할 때 사용된다. 서버에서는 클라이언트로부터 리소스를 식별할 수 있는 값을 받아 데이터베이스나 캐시에 있는 리소스를 조회하고 삭제하는 역할을 수행한다. 이때 컨트롤러에서는 값을 간단히 받기 때문에 GET 메서드와 같이 URI에 값을 넣어 요청을 받는 형식으로 구현된다.
@PathVariable과 @RequestParam을 활용한 DELETE 메서드 구현
@PathVariable을 이용하면 아래 예제와 같이 URI에 포함된 값을 받아 로직을 처리할 수 있다.
// http://localhost:8080/api/v1/delete-api/{String 값}
@DeleteMapping(value = "/{variable}")
public String DeleteVariable(@PathVariable String variable) {
return variable;
}
주의해야 할 점은 @DeleteMapping에서 지정한 value 값과 매개변수의 이름을 동일하게 설정해야 한다. 그게 구조상 어렵다면 @PathVariable의 value 옵션을 통해 같은 값을 지정한 후 사용하면 된다.
@RequestParam을 이용하면 쿼리스트링 값도 받아 올 수 있다.
// http://localhost:8080/api/v1/delete-api/request1?email=value
@DeleteMapping(value = "/request1")
public String getRequestParam1(@RequestParam String email) {
return "e-mail : " + email;
}
'Framework > Spring' 카테고리의 다른 글
[Spring] 로그를 남겨주는 라이브러리 - Logback (0) | 2023.10.13 |
---|---|
[Spring] REST API를 명세하는 방법 - Swagger (1) | 2023.10.11 |
[Spring] GET API를 구현하는 다양한 방법 (0) | 2023.10.06 |
[Spring] REST API 란? (0) | 2023.10.05 |
[Spring] 레이어드 아키텍처와 스프링의 레이어드 아키텍처 (0) | 2023.10.05 |