(20) Spring Official Tutorial - Building REST service with Spring

HEYDAY7·2022년 11월 9일
0

Learn Kotlin + Spring

목록 보기
21/25

시작하며

지난 주말부터 바쁜일이 있어 commit은 물론 글조차도 꽤나 오랜만이다.(3?4일) 중간중간 짬짬이 본 튜토리얼을 진행은 했는데 이제 와서야 정리를 하게 되었다.

Building REST services with Spring

https://spring.io/guides/tutorials/rest/

튜토리얼 시리즈의 경우 코드를 주로 다루는 것 보다도 튜토리얼이 전달하고자 하는 개념이 먼지, 그 핵심을 정리해보고자 한다.

한줄 요약

기본 베이스를 이루는 내용은 RESTFul 하게 서버를 구성하는데 있어서 알면 좋을 내용들을 전해준다.

코드

코드의 경우 튜토리얼이라 상당히 길기 때문에 상세한 코드는 github에서 직접 확인해보는 것을 추천한다.

Controller

Controller를 만들 때는 기초는 간단하다.

  1. @RestController annotation을 추가해준다.
  2. 해당 Controller에서 필요한 repository를 parameter로 받아와준다.
    여기서 Repository의 경우 특별한 구현이 필요하지 않을 경우 알맞는 Repository를 상속받아주자.
  3. 각 method에 맞는 REST method annotation을 달아준다.(@GetMapping, @PostMapping, @PutMapping, @DeleteMapping) 이때 endpoint를 적어주는 것을 잊지 말자.
  4. repository의 method들을 이용해 각 요청에 맞는 entity를 return 해주자.

Exception, Handler

Exception을 custom하게 만들어 관리하는 것도 좋은 코드를 만드는 습관 중 하나라고 생각한다. 튜토리얼에서 알려주는 방식은 다음과 같다
1. CustomException class를 기존 Exception을 상속받아 만든다.
2. @ControllerAdvice annotation을 이용해서 advice class를 만들고, Handler function을 만들어준다.
3. 해당 function에서 @ExceptionHandler annotation을 통해서 Exception을 설정해주고, @ResponseStatus로 HttpStatus를 돌려주면된다.


RESTful 하게 작성하기(Hypermedia-driven REST)

여기까지만 작성하더라도 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를 이용해서 실현할 수 있다.

이를 보고서는 음... 이게 어떠한 큰 이점이 있는건지가 헷갈렸다. 그래서 추가적으로 조사를 해 보았다. 그랬더니 아주 유용한 글을 발견했다.

  • REST with Hypermedia - Hot or Not?
    이는 Hypermedia를 REST에 포함시키는 것에 대한 장점과 단점을 알려주고 있다. 요약하자면 아래와 같다.

장점

  • client가 endpoint들을 모두 다 알지 못해도 된다.
  • client 코드의 변화 없이 action을 수정할 수 있다. 이게 가능한 이유는 client에서 link의 제공 여부를 보고 특정 판단을 하게 하거나, 해당 link를 그대로 사용하여 요청을 할 수 있기 때문이다.

단점

  • client에서 hardcoded link를 써버리면 의미가 없다.
  • client에서 여러 link들의 연관성을 파악해아 한다. 서비스가 커지고 복잡해질 경우 큰 resource가 필요할 수 도 있다.
  • 확실하게 정해진 규격이 없다.
  • Response 가 매우 커진다.(embeddeds, links 등)

결론

나도 읽어봤지만 아직 확신이 스지는 않는다. 다만 핵심이 되는 장점과 단점은 파악이 된다. 우선 client 코드 변화 없이 로직을 변경할 수 있다는 점은 크나큰 장점으로 보인다. 다만 정해진 규격이 없어 어느 한 client에서라도 hardcoded linkt를 쓰기 시작하면 의미가 없다는 것 또한 매우 커 보인다. 따라서 나 또한 특별한 니즈가 있는게 아니라면 아직은 시기상조라고 생각은 한다. 다만 방법을 알아둬서 나쁠게 없기에 이번 튜토리얼에서는 해당 방식으로의 진행을 따라가보았다.

HATEOAS를 이용하기

우선 HATEOAS가 지원하는 몇몇 class들을 설명하고 넘어간다.

  • EntityModel<?> : ? 타입의 Return과 함께 link를 묶어 구성하는 모델
  • CollectionModel<EntityModel<?>> : 그런 EntityModel을 collection 형태로 encapsulating 해주는 container이다.

또 반복적인 Link 코드 생성을 지양하기 위해 Assembler를 사용할 것을 추천해준다. 예를 들어 (? -> EntityModel<?>)인 toModel function을 만들어 재사용하는 것이다.

그 후 controller의 function들의 흐름은 동일하다.

  • 요청에 대한 응답은 형태의 경우 CollectionModel, EntityModel의 형태로 return 해준다. 이 과정에서 각 container에 관련된 link들을 넣어서 만들어주고, 이 때 assembler를 이용해 코드 반복을 줄여준다.

프로젝트 마무리

사실 핵심적인 내용은 이정도가 끝이다. 그 이후는 실제로 코드를 작성하고 테스트 해보는 정도가 끝이다. 사실 link를 왜 넣어야해? 라는 생각이 크게 든다면 그렇게 까지 열심히 들여다볼 튜토리얼은 아닐 수도 있다. 다만 얕게라도 넓게 알아두는 것도 나쁘지 않으니 가볍게 봐보는 정도는 추천한다.

마치며

이번 튜토리얼의 경우 처음에는 매우 해맸다. 갑자기 link는 왜 튀어나오는 거고, java 코드를 kotlin으로 바꿔가며 작성하다 보니 삽질도 많이 했다. 다만 Hyperlink driven REST에 대한 개념을 이해하고 나니 어떤 작업을 하려 했던 것인지 알겠고, 사실 그렇게까지 힘을 쓰지 않아도 됬었던 것 같다. 해당 내용을 잊지만 말아두자.

profile
(전) Junior Android Developer (현) Backend 이직 준비생

0개의 댓글