Rest 의미
Representational State Transfer 의 약자로 소프트웨어 프로그램 개발의 아키텍처의 한형식이며 좁은 의미로 HTTP를 통해 CRUD 를 실행하는 API 를 뜻한다.
출처 : https://www.a-mean-blog.com/ko/blog/%ED%86%A0%EB%A7%89%EA%B8%80/_/REST%EC%99%80-RESTful-API
CRUD : Create, Read, Update, Delete의 약어. 데이터의 생성,조회,수정,삭제 가능함을 나타냄.
RESTful
- Rest의 비공식적 구현 가이드.
- Restful 중 가장 대표적이며 보편적인 규칙이 확고하게 정해진 RESTful routing에 대해 간단한 예를 들어 알아보겠습니다.
[GET]/products : 전체 product list 를 호출
[GET]/products/1 : 1번 id를 가진 product 호출
[POST]/products : 새 product 등록
[PUT]/products/1 : 1번 id를 가진 product 정보 수정
[DELETE]/products/1 : 1번 id를 가진 product 정보 삭제
@RestController
Spring4 에서 Rest API 또는 Web API 를 개발하기 위해 Spring MVC가 제공하는 애노테이션.
참고1. Spring 3 에서는 @Controller 와 @ResponseBody를 사용
참고2. Spring4 에서는 Rest API 또는 WEB API를 개발하기 위해서 @RestController가 추가되었고 이전버전의 @Controller, @ResponseBody 도 포함되어있음.
MessageConvertor
@RestController 사용하기 위해서는 자바 객체와 HTTP 요청 및 응답을 변환하는 역할을 하는 MessageConvertor 를 사용해야 합니다.
외부에서 전달받은 JSON 메서드를 내부에서 사용가능하도록 객체로 변환하거나, 컨트롤러가 리턴한 객체를 클라이언트에게 JSON 형태로 변환해 전달하는 역할을 하는것이 MessageConvertor가 가능하게 해줍니다.
MessageConvertor는 jackson라이브러리 사용하는데 이 라이브러리가 제대로 추가되어있지 않으면 JSON을 처리하는 Convertor가 등장하지 않아서 500번 오류 발생해 반드시 jackson 라이브러리를 아래와 같이 추가해야 정상적으로 사용가능합니다.
아래와 같이 추가하고 @RestController 선언하여 Rest API의 컨트롤러 역할을 하는 클래스를 구현해주면 됩니다.
...
<!-- Jackson Module -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson2.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
<version>${jackson2.version}</version>
</dependency>
...
JSON
컨트롤러의 메소드에서는 JSON 으로 변환될 객체를 반환합니다. jackson라이브러리를 추가할 경우 객체를 JSON으로 변환하는 메시지 컨버터가 사용되도록 @EnableWebMvc에서 기본으로 설정되어있습니다. 사용자가 임의의 MessageConverter를 사용하도록 하려면 WebMvcConfigurerAdapter의 configureMessageConverters메소드를 오버라이딩 하도록 합니다.
Web API 에서 JSON 메시지를 자주 사용하는 이유?
JSON과 XML 모두 데이터를 저장하고 전달하기 위해 고안되었습니다. 두 언어 모두 기계 뿐만 아니라 사람도 쉽게 읽을 수 있고 계층적인 데이터 구조를 가지고있습니다. 또한 다양한 프로그래밍 언어에 의해 파싱될 수 있고 XMLHttpRequest 객체를 이용해 서버로부터 데이터를 전송받을 수 있습니다.
그런데 왜 xml이 아니고 JSON 메시지를 사용할까요? XML은 배열을 사용할 수 없지만, JSON은 배열을 사용할 수 있고 XML문서는 XML DOM을 이용해 해당 문서에 접근해야하지만, JSON은 문자열을 전송받은 이후 바로 파싱해 XML보다 빠른 처리 속도를 보여줘 html과 자바스크립트가 연동되어 빠른 응답이 필요한 웹 환경에서 많이 사용됩니다.
(출처-http://tcpschool.com/json/json_intro_xml)
RestController를 이용해 web API를 작성하기
위의 이미지처럼 Method 는 GET 으로 두고 URL에 본인의 로컬호스트주소/guestBooks 입력후 send 버튼 클릭시 전체 리스트를 받아오도록 하는 web API 코드를 살펴보겠습니다. (위의 이미지는 chrome 브라우저에서 제공하는 확장 앱 Restlet Client 입니다)
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import kr.or.connect.guestbook.dto.Guestbook;
import kr.or.connect.guestbook.service.GuestbookService;
@RestController
@RequestMapping(path="/guestbooks")
public class GuestbookApiController {
@Autowired
GuestbookService guestbookService;
@GetMapping
public Map<String, Object> list(@RequestParam(name="start", required=false, defaultValue="0") int start) {
List<Guestbook> list = guestbookService.getGuestbooks(start);
int count = guestbookService.getCount();
int pageCount = count / GuestbookService.LIMIT;
if(count % GuestbookService.LIMIT > 0)
pageCount++;
List<Integer> pageStartList = new ArrayList<>();
for(int i = 0; i < pageCount; i++) {
pageStartList.add(i * GuestbookService.LIMIT);
}
Map<String, Object> map = new HashMap<>();
map.put("list", list);
map.put("count", count);
map.put("pageStartList", pageStartList);
return map;
}
@PostMapping
public Guestbook write(@RequestBody Guestbook guestbook,
HttpServletRequest request) {
String clientIp = request.getRemoteAddr();
// id가 입력된 guestbook이 반환된다.
Guestbook resultGuestbook = guestbookService.addGuestbook(guestbook, clientIp);
return resultGuestbook;
}
}
@RequestMapping: URL 요청이 모두 /guestbooks 로 공통으로 받아서 처리할 수 있도록 클래스 상단에 @RequestMapping(path="/guestbooks") 값 설정합니다.
@RequestParam: GET 방식으로 url이 넘어올 경우 변수값이 있을때 받아 처리하도록 하는 어노테이션.
@RequestBody : 이 어노테이션이 붙은 파라미터에는 HTTP 요청의 본문 body 부분이 그대로 전달된다. 다시말해 HTTP 요청 Body를 자바 객체로 전달받을 수 있는 어노테이션
메소드 안에서 요청에 알맞은 리스트 데이터를 서비스클래스로부터 받아 Map 객체에 담아 반환합니다. 이때, Map 객체는 자동으로 JSON 형태로 변환되어 클라이언트에게 전달됩니다.
출처 - https://devyj.tistory.com/3
https://www.edwith.org/boostcourse-web/lecture/16774/