[SpringData JPA] HATEOAS

hyewon jeong·2023년 2월 5일
0

Spring

목록 보기
36/59

본 글을 개인공부를 위해 참고자료에서 가져온 글입니다.

HATEOAS 란?

Hypermedia As The Engine of Application State 의 약자

간단히 말해서 다음 요청을 위한 하이퍼링크가 제공되어야 한다!!!

💁‍♀️ 얼만큼? 클라이언트 화면이 필요 없을 만큼!!

  • 서버리스가 아닌 클라이언트리스…

HATEOAS 적용 예시

예를 들어 게시글 조회 API를 호출했을때

{
  "data": {
    "id": 1000,
    "name": "게시글 1",
    "content": "HAL JSON을 이용한 예시 JSON",
    "self": "http://localhost:8080/api/post/1000", // 호출한 api 주소
    "profile": "http://localhost:8080/docs#query-article", // 호출한 api 문서
    "next": "http://localhost:8080/api/post/1001", // 다음 post를 조회 api 주소
    "comment": "http://localhost:8080/api/post/comment", // post의 댓글 달기 api 주소
    "save": "http://localhost:8080/api/feed/post/1000", // post을 내 피드로 저장 api 주소
  },
}

HATEOAS 를 SpringData JPA 페이징에 적용하기

SpringDataJPA 에서도 페이지를 응답할때 페이지 정보만 응답하는것이 아니라
이전/다음페이지를 조회하기 위한 링크를 바로 제공해줄 수 있다.

적용 방법

  1. HATEOAS 의존성 추가 (spring-boot-starter-hateoas)
// 9. SpringBoot HATEOAS 의존성 추가
implementation 'org.springframework.boot:spring-boot-starter-hateoas'
  1. 핸들러 매개변수로 PagedResourcesAssembler 넣고 PagedModel 로 응답
@RestController
public class ChannelController {

  @Autowired
  ChannelRepository channelRepository;

  @GetMapping("/channels")
  public PagedModel<User> getUsers(Pageable pageable, PagedResourcesAssembler<User> assembler) {
    var all = channelRepository.findAll(pageable);
    return assembler.toModel(all);
  }

}

적용 결과

  • 적용 전 응답 (기본 Pageable)
{  
   "content":[  
...
      {  
         "id":140,
         "title":"jpa"
      }
   ],
   "pageable":{  
      "sort":{  
         "sorted":true,
         "unsorted":false
      },
      "offset":20,
      "pageSize":10,
      "pageNumber":2,
      "unpaged":false,
      "paged":true
   },
   "totalElements":200,
   "totalPages":20,
   "last":false,
   "size":10,
   "number":2,
   "first":false,
   "numberOfElements":10,
   "sort":{  
      "sorted":true,
      "unsorted":false
   }
}
  • 적용 후 응답 (PageModel (PagedResource))
{  
   "_embedded":{  
      "channelList":[  
         {  
            "id":140,
            "title":"jpa"
         },
...
         {  
            "id":109,
            "title":"jpa"
         }
      ]
   },
   "_links":{  
      "first":{  
         "href":"http://localhost/channels?page=0&size=10&sort=created,desc&sort=title,asc"
      },
      "prev":{  
         "href":"http://localhost/channels?page=1&size=10&sort=created,desc&sort=title,asc"
      },
      "self":{  
         "href":"http://localhost/channels?page=2&size=10&sort=created,desc&sort=title,asc"
      },
      "next":{  
         "href":"http://localhost/channels?page=3&size=10&sort=created,desc&sort=title,asc"
      },
      "last":{  
         "href":"http://localhost/channels?page=19&size=10&sort=created,desc&sort=title,asc"
      }
   },
   "page":{  
      "size":10,
      "totalElements":200,
      "totalPages":20,
      "number":2
   }
}

💡 잠시! 꿀팁

  • JPA 로 쿼리를 짜기 매우 어려운데 왜 다들 JPA만 쓰나요?
    • JPA로 많이 넘어간 까닭은, 데이터모델이 단순해진 탓이라고 봅니다.
    • 대신 데이터 흐름이 매우 정교 해졌고요.
    • DDD(도메인 주도 개발)이 중심이 되어가고 있기때문에.
    • MSA 를위해 도메인 중심으로 모듈이 분리될 수 있는 구조로 프로젝트들이 발전해오고 있다.

참고

  • 스파르타코딩 강의 자료
profile
개발자꿈나무

0개의 댓글