~11.3 REST API 구현하기(종이책 p.303~332)
※ JSON의 값으로 또다른 JSON 데이터나 배열을 넣을 수도 있다.
REST API 란 REST 기반으로 API를 구현한 것이라고 할 수 있다. REST API를 잘 구현하면 클라이언트가 기기에 구애받지 않고 서버의 자원을 이용할 수 있을 뿐만 아니라, 서버가 클라이언트의 요청에 체계적으로 대응할 수 있어서 서버 프로그램의 재사용성과 확장성이 좋아진다.
REST API를 구현하려면 REST API의 주소, 즉 URL을 설계해야 한다.
이전에 만든 게시판의 Article 데이터를 CRUD하기 위해 REST API 주소를 다음과 같이 설계한다.
주소 설계가 끝났다면 URL 요청을 받아 그 결과를 JSON으로 반환해 줄 컨트롤러도 만들어야한다.
게스판을 만들 때는 일반 컨트롤러(ArticleController)를 사용했지만, REST API로 요청과 응답을 주고받을 때는 REST 컨트롤러를 사용한다. 또한 응답할 때 적절한 상태 코드를 반환하기 위해 ResponseEntity라는 클래스도 활용한다.
com.example.firstproject에 새로운 패키지를 만든다. 이름은 마지막에 api를 붙인 com.example.firstporject.api로 생성한다.
먼저 간단하게 REST API의 동작을 구현하며 REST 컨트롤러의 개념을 이해해본다.
public class FirstApiController{
@GetMapping(”/api/hello”)
public String hello(){
return “hello world!”;
}
}
http://localhost:8080/api/hello를 URL로 입력하고 Send 해보면 응답이 200으로 오는 것을 확인할 수 있다.이전에 만든 FirstController를 열면 “/hi”라는 URL 요청을 보냈을 때 greetings.mustache 파일을 반환하도록 되어있다. 이를 Talend API Tester에서 테스트해 보면 응답 BODY에 HTML 코드가 있는 것을 확인할 수 있다.
즉, REST 컨트롤러는 JSON이나 텍스트 같은 데이터를 반환하는 반면 일반 컨트롤러는 뷰 페이지를 반환한다는 차이점이 있는 것이다.
이제 본격적으로 게시판 데이터의 CRUD를 위한 REST API를 구현해본다.
먼저 GET 요청을 받아 처리할 메서드를 만들어 본다.
List<Article>인 index()라는 메서드를 정의한다.
http://localhost:8080/api/articles로 보내면 Article 데이터 3개가 응답으로 오는 것을 확인할 수 있다.이번에는 모든 게시글이 아닌 단일 게시글만 조회하는 요청을 처리해본다.

데이터 생성 요청을 받아 처리할 메서드를 만든다.
@PostMapping으로 “/api/articles” 주소로 오는 URL 요청을 받는다.
반환형이 Article인 create()라는 메서드를 정의하고 데이터를 dto 매개변수로 받아 온다.
이렇게 받아온 dto는 DB에서 활용할 수 있도록 엔티티로 변환해 article 변수에 넣고, articleRepository를 통해 DB에 저장한 후 반환한다.
서버를 재시작하고 Talend API Tester에서 POST 요청으로 { “title”: “AAAA”, “content”: “123123” }으로 보내면 성공 응답은 돌아오지만 응답 본문에 title과 content가 null로 나온다.
웹 페이지에 게시판 폼을 만들고 데이터를 생성할 때는 컨트롤러의 메서드에 매개변수로 dto를 받아 오기만 하면 됐지만, REST API에서 데이터를 생성할 때는 JSON 데이터를 받아 와야 하므로 dto 매개변수 앞에 @RequestBody라는 어노테이션을 추가해 줘야 한다.
이렇게 추가하면 요청 시 본문(BODY)에 실어 보내는 데이터를 create() 메서드의 매개변수로 받아 올 수 있다.

서버를 재시작하고 Send 버튼을 누르면 성공적으로 title과 content도 생성된 것을 확인할 수 있다.
DB에 접속해서 확인해도 잘 생성된 것을 확인할 수 있다.
데이터 수정 요청을 받아 처리할 메서드를 만든다.
@PatchMapping으로 “/api/articles/{id}” 주소로 오는 URL 요청을 받는다.
반환형이 Article인 update()라는 메서드를 정의하고 매개변수로 요청 URL의 id와 요청 메시지의 본문 데이터를 받아온다.
먼저 수정용 엔티티를 만든다.
DB에 대상 엔티티가 있는지 조회해 가져온다.
잘못된 요청이 들어온 경우를 처리한다.
ResponseEntity<Article>로 바꿔준다.※ ResponseEntity는 REST 컨트롤러의 반환형, 즉 REST API의 응답을 위해 사용하는 클래스이다. REST API 요청을 받아 응답할 때 이 클래스에 HTTP 상태 코드, 헤더, 본문을 실어 보낼 수 있다.
마지막으로 정상 응답을 처리한다.
이 과정까지 하고 수정 요청을 하면 정상적으로 작동하는 것을 확인할 수 있지만, 데이트의 일부분(title은 빼고)만 수정하겠다고 요청을 보내면 성공 응답은 오지만 수정하는 것 외의 부분(title)은 null값이 되어 기존 값이 날라간다.
target에는 기존 데이터가 있고, article에는 수정할 데이터가 있으므로 기존 데이터에 새 데이터를 붙여 주면 일부 데이터만 수정할 수 있다.
Article 엔티티 코드에 patch() 메서드를 작성한다.
public void patch(Article article) {
if(article.title != null)
this.title = article.title;
if(article.content != null)
this.content = article.content;
}
target에 patch() 메서드로 article(수정할 내용만)을 붙인다. 그리고 최종적으로 target을 DB에 저장한다.

DELETE 요청을 받아 처리할 메서드를 만든다.
<Article>을 실어 보내는 delete()라는 메서드를 정의하고 URL의 id를 매개변수로 받아온다.
http://localhost:8080/api/articles/2 URL을 주면 성공 응답이 오는 것을 볼 수 있고, 실제 DB에도 삭제된 모습을 볼 수 있다.