POST API 만들기
POST API는 웹 애플리케이션을 통해 데이터베이스 등의 저장소에 리소스를 저장할때 사용되는 PAI입니다. GET API에서는 URL의 경로나 파라미터에 변수를 넣어 요청을 보냈지만 POST API 에서는 저장하고자 하는 리소스나 값을 HTTP 바디(body)에 담아 서버에 전달합니다. 그래서 URI가 GET API에 비해 간단합니다.
POST API를 만들기 위해 우선 아래 예제와 같이 PostController라는 이름의 컨트롤러 클래스를 생성하고 @RequestMapping 어노테이션을 이용해 공통 URL을 설정합니다.
package com.springboot.api.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/v1/post-api")
public class PostController {
}
@RequestMapping으로 구현하기
POST API에서 @ReqeustMapping을 사용하는 방법은 GET API와 크게 다르지 않습니다.요청 처리 메서드를 정의할 때 아래 예제처럼 method 요소를 RequestMethod.POST로 설정하는 부분을 제외하면 GET API와 동일합니다.
@RequestMapping(value = "/domain", method = RequestMethod.POST)
public String postExample(){
return "Hello Post API";
}
@RequestBody를 활용한 POST 메서드 구현
위 예제에서는 별도의 리소스를 받지 않고 단지 POST 요청만 받는 메서드를 구현했습니다. 일반적으로 POST 형식의 요청은 클라이언트가 서버에 리소스를 저장하는 데 사용합니다. 그러므로 클라이언트의 요청 트래픽에 값이 포함돼 있습니다. 즉, POST 요청에서는 리소스를 담기 위해 HTTP Body에 값을 넣어 전송합니다.
Body 영역에 작성되는 값은 일정한 형태를 취합니다. 일반적으로 JSON(JavaScript Object Notation)형식으로 전송됩니다.
// http://localhost:8080/api/v1/post-api/member
@PostMapping(value = "/member")
public String postMember(@RequestBody Map<String, Object> postData) {
StringBuilder sb = new StringBuilder();
poostData.entrySet().forEach(map -> {
sb.append(map.getKey() + " : " + mpa.getValue() + "\n");
});
return sb.toString();
}
위 예제의 2번 줄을 보면 @RequestMapping 대신 @PostMapping을 사용했습니다. 이 어노테이션을 사용하면 method 요소를 정의하지 않아도 됩니다. 그리고 3번 줄에서 @RequestBody라는 어노테이션을 사용했는데, @RequestBody는 HTTP의 Body 내용을 해당 어노테이션이 지정된 객체에 매핑하는 역할을 합니다.
참고로 JSON이란?
JSON은 'JavaScript Object Notation'의 줄임말로 자바스크립트의 객체 문법을 따르는 문자 기반의 데이터 포맷입니다. 현재는 자바스크립트 외에도 다수의 프로그래밍 환경에서 사용합니다. 대체로 네트워크를 통해 데이터를 전달할 때 사용하며, 문자열 형태로 작성되기 때문에 파싱하기도 쉽다는 장점이 있습니다.
Map객체는 요청을 통해 어떤 값이 들어오게 될지 특정하기 어려울 때 주로 사용합니다. 요청 메시지에 들어갈 값이 정해져 있다면 아래 예제와 같이 DTO 객체를 매개변수로 삼아 작성할 수 있습니다.
// http://localhost:8080/api/v1/post-api/member2
@PostMapping(value = "/member2")
public String postMemberDto(@RequestBody MemberDto memberDto){
return memberDto.toString();
}
위와 같이 작성하면 MemberDto의 멤버 변수를 요청 메시지의 키와 매핑해 값을 가져옵니다.
PUT API 만들기
PUT API는 웹 애플리케이션 서버를 통해 데이터베이스 같은 저장소에 존재하는 리소스 값을 업데이트하는 데 사용합니다. POST API와 비교하면 요청을 받아 실제 데이터베이스에 반영하는 과정(서비스로직)에서 차이가 있지만 컨트롤러 클래스를 구현하는 방법은 POST API와 거의 동일합니다. 리소스를 서버에 전달하기 위해 HTTP Body를 활요해야 하기 때문입니다.
먼저 아래예제와 같이 PutController라는 컨트롤러 클래스를 작성합니다.
@RestController
@RequestMapping("/api/v1/put-api")
public class PutController {
}
@RequestBody를 활용한 PUT 메서드 구현
PUT API는 POST 메서드와 마찬가지로 값을 HTTP Body에 담아 전달합니다. 서버에서는 이 값을 받기 위해 아래 예제와 같이 @RequestBody를 사용합니다
// http://localhost:8080/api/v1/put-api/member
@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();
}
서버에 어떤 값이 들어올지 모르는 경우에는 Map 객체를 활요해 값을 받을 수 있습니다. 대부분의 경우 API를 개발한 쪽에서 작성한 명세를 웹 사이트를 통해 클라이언트나 사용자에게 올바른 사용법을 안내합니다. 만약 서버에 들어오는 요청에 담겨 있는 값이 정해져 있는 경우에는 아래 예제와 같이 DTO객체를 활용해 구현합니다.
// http://localhost:8080/api/v1/put-api/member1
@PutMapping(value = "/member1")
public String postMemberDto1(@RequestBody MemberDto memberDto) {
return memberDto.toString();
}
// htpp://localhost:8080/api/v1/put-api/member2
@PutMapping(value = "/member2")
public MemberDto postMemberDto2(@RequestBody MemberDto memberDto){
return memberDto;
}
위의 예제는 2개의 메서드로 구성돼 있습니다. 첫 번째 메서드인 postMemberDto1은 리턴 값이 String타입이고, 두 번째 메서드인 postMemberDto2는 DTO 객체 타입입니다. 이전 예제에서는 String 타입만 소개했는데, 여기서는 DTO 객체를 반환할 때는 어떤 차이가 있는지 보겠습니다.
이 요청을 보내면 String 타입으로 값을 전달받게 되며, 4번째 줄에 작성한대로 리턴 값으로 설정한 DTO 객체의 toString 메서드 결과값이 출력됩니다.
출력 결과를 보면 보낸 요청 내용이 그대로 결괏값으로 전달된 것을 볼 수 있습니다. toString 메서드로 인해 나름의 형식이 갖춰져 전달됐지만 HEADERS 항목의 content-type을 보면 'text/plain' 으로서 결괏값으로 일반 문자열이 전달됐음을 확인할 수 있습니다.
이번에는 동일한 값을 담고 URL만 변경해서 두 번째 메서드에 대한 테스트를 진행하겠습니다.
이번엔 application/json 형식으로 전달된 것을 확인할 수 있습니다. @RestController 어노테이션이 지정된 클래스는 @ResponseBody를 생략할 수 있는데 이 @ResponseBody 어노테이션은 자동으로 값을 JSON과 같은 형식으로 변환해서 전달하는 역할을 수행합니다.
@ResponseEntity를 활용한 PUT 메서드 구현
스프링 프레임워크에는 HttpEntity라는 클래스가 있습니다. HttpEntity는 다음과 같이 헤더(Header)와 Body로 구성된 HTTP 요청과 응답을 구성하는 역할을 수행합니다.
public class HttpEntity<T> {
private final HttpHeaders headers;
@Nullable
private final T body;
...
}
RequestEntity와 ResponseEntity는 HttpEntity를 상속받아 구현한 클래스입니다. 그중 ResponseEntity는 서버에 들어온 요청에 대해 응답 데이터를 구성해서 전달할 수 있게 합니다. 다음과 같이 ResponseEntity는 HttpEntity로부터 HttpHeaders와 Body를 가지고 자체적으로 HttpStatus를 구현합니다.
public class ResponseEntity<T> extends HttpEntity<T> {
private final object status;
...생량..
}
이 클래스를 활용하면 응답 코드 변경은 물론 Header와 Body를 더운 쉽게 구성할 수 있습니다. 이 클래스는 PUT메서드를 구현하는 이번 내용에서 소개하고 있지만 다른 메서드에서도 모두 사용할 수 있는 클래스입니다.
아래 예제는 메서드의 리턴 타입에 ResponseEntity를 적용한 예입니다.
// http://localhost:8080/api/v1/put-api/member3
@PutMapping(value = "/member3")
public ResponseEntity<MemberDto> postMemberDto3(@RequestBody MemberDto memberDto) {
return ResponseEntity
.status(HttpStatus.ACCEPTED)
.body(memberDto);
}
위 예제의 3번 줄에서는 메서드의 리턴 타입을 ResponseEntity로 설정하고 4~6번 줄에서 리턴 값을 만듭니다. status에 넣을 수 있는 값은 다양한데, 예제에서 사용한 HttpStatus.ACCEPTED는 응답 코드 202를 가지고 있습니다. 즉, 이 메서드를 대상으로 요청을 수행하면 아래와 같이 응답 코드가 202로 변경됩니다.
DELETE API 만들기
DELETE API는 웹 애플리케이션 서버를 거쳐 데이터베이스 등의 저장소에 있는 리소스를 삭제할 때 사용합니다. 서버에서는 클라이언트로부터 리소스를 식별할 수 있는 값을 받아 데이터베이스나 캐시에 있는 리소스를 조회하고 삭제하는 역할을 수행합니다. 이때 컨트롤러를 통해 값을 받는 단계에서는 간단한 값을 받기 때문에 GET 메서드와 같이 URI에 값을 넣어 요청을 받는 형식으로 구현됩니다.
먼제 아래예제와 같이 컨트롤러 클래스를 작성합니다. 이 컨트롤러에서 작성하는 메서드는 GET메서드를 작성하는 방법과 동일하므로 간단하게 소개하겠습니다.
@RestController
@RequestMapping("/api/v1/delete-api")
public class DeleteController {
}
@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의 이름과 메서드의 매개변수 이름을 동일하게 설정해야 삭제할 값이 주입됩니다. 또는 @RequestParam 어노테이션을 통해 쿼리스트링 값도 받을 수 있습니다.
// http://localholst:8080/api/v1/delete-api/request1?email=value
@DeleteMapping(value = "/request1")
public String getRequestParam1(@RequestParam String email) {
return "e-mail : " + email;
}
'웹 개발 > 🍃 SpringBoot' 카테고리의 다른 글
JPA | JPA (0) | 2025.01.07 |
---|---|
JPA | ORM (1) | 2025.01.07 |
SpringBoot | GET API를 작성하는 방법 (0) | 2024.12.23 |
JUnit5 | 기본 테스트 어노테이션 (0) | 2024.12.18 |
Project Metadata - spring initializr 정복하기(4) (1) | 2024.12.17 |