지난 주말부터 바쁜일이 있어 commit은 물론 글조차도 꽤나 오랜만이다.(3?4일) 중간중간 짬짬이 본 튜토리얼을 진행은 했는데 이제 와서야 정리를 하게 되었다.
https://spring.io/guides/tutorials/rest/
튜토리얼 시리즈의 경우 코드를 주로 다루는 것 보다도 튜토리얼이 전달하고자 하는 개념이 먼지, 그 핵심을 정리해보고자 한다.
기본 베이스를 이루는 내용은 RESTFul 하게 서버를 구성하는데 있어서 알면 좋을 내용들을 전해준다.
코드의 경우 튜토리얼이라 상당히 길기 때문에 상세한 코드는 github에서 직접 확인해보는 것을 추천한다.
Controller를 만들 때는 기초는 간단하다.
Exception을 custom하게 만들어 관리하는 것도 좋은 코드를 만드는 습관 중 하나라고 생각한다. 튜토리얼에서 알려주는 방식은 다음과 같다
1. CustomException class를 기존 Exception을 상속받아 만든다.
2. @ControllerAdvice annotation을 이용해서 advice class를 만들고, Handler function을 만들어준다.
3. 해당 function에서 @ExceptionHandler annotation을 통해서 Exception을 설정해주고, @ResponseStatus로 HttpStatus를 돌려주면된다.
여기까지만 작성하더라도 CRUD도 잘 되고, 원하는 데로 return도 오고 하지만 이는 RESTFul 하게 작성한 것이 아니라고 한다. 오히려 RPC(Remote Procedure Cell)에 가깝다고 한다. 튜토리얼에서 말해주는 요지는 다음과 같다.
"단순히 HTTP-based interface를 REST API라고 불러서는 안된다. 여기어 hypermedia 를 포함해야 한다."
Roy Fielding의 글에서 한 말의 요약이다.
https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
Spring 에서는 Spring HATEOAS를 이용해서 실현할 수 있다.
이를 보고서는 음... 이게 어떠한 큰 이점이 있는건지가 헷갈렸다. 그래서 추가적으로 조사를 해 보았다. 그랬더니 아주 유용한 글을 발견했다.
나도 읽어봤지만 아직 확신이 스지는 않는다. 다만 핵심이 되는 장점과 단점은 파악이 된다. 우선 client 코드 변화 없이 로직을 변경할 수 있다는 점은 크나큰 장점으로 보인다. 다만 정해진 규격이 없어 어느 한 client에서라도 hardcoded linkt를 쓰기 시작하면 의미가 없다는 것 또한 매우 커 보인다. 따라서 나 또한 특별한 니즈가 있는게 아니라면 아직은 시기상조라고 생각은 한다. 다만 방법을 알아둬서 나쁠게 없기에 이번 튜토리얼에서는 해당 방식으로의 진행을 따라가보았다.
우선 HATEOAS가 지원하는 몇몇 class들을 설명하고 넘어간다.
또 반복적인 Link 코드 생성을 지양하기 위해 Assembler를 사용할 것을 추천해준다. 예를 들어 (? -> EntityModel<?>)인 toModel function을 만들어 재사용하는 것이다.
그 후 controller의 function들의 흐름은 동일하다.
사실 핵심적인 내용은 이정도가 끝이다. 그 이후는 실제로 코드를 작성하고 테스트 해보는 정도가 끝이다. 사실 link를 왜 넣어야해? 라는 생각이 크게 든다면 그렇게 까지 열심히 들여다볼 튜토리얼은 아닐 수도 있다. 다만 얕게라도 넓게 알아두는 것도 나쁘지 않으니 가볍게 봐보는 정도는 추천한다.
이번 튜토리얼의 경우 처음에는 매우 해맸다. 갑자기 link는 왜 튀어나오는 거고, java 코드를 kotlin으로 바꿔가며 작성하다 보니 삽질도 많이 했다. 다만 Hyperlink driven REST에 대한 개념을 이해하고 나니 어떤 작업을 하려 했던 것인지 알겠고, 사실 그렇게까지 힘을 쓰지 않아도 됬었던 것 같다. 해당 내용을 잊지만 말아두자.