Spring Data JPA - HATEOAS

Spring Data JPA

백기선님의 강의인 Spring Data JPA 강의를 듣고 공부한 내용을 정리한 글

HATEOAS

Spring Data Common이 지원하는 웹 기능 중 HATEOAS에 대해서 살펴보자.

HATEOAS는 REST API의 규약 중 하나이기도 한데, 간단하게 이야기하면 REST API 응답만 보더라도 해당 자원의 이전, 다음과 같은 정보들이 URL로 존재해야한다는 규약이다.

springboot에서 hateoas 관련 의존성을 추가하면 사용이 가능하다.

이전 시간에 만든 예제를 확장해보자.

주의해야할 점은 기선님의 강의에서 스프링 부트 2.2.2에서 PagedResourcesAssembler의 형태가 조금 바뀌었다.

Before 2.2.2 이전

@GetMapping("/test)
fun getPosts(pageable:Pageable, assembler:PagedResourcesAssembler): PagedResources<Page<Post>> {
    val all = postRepository.findAll(pageable)
    return assembler.toResource(all)
}

After 2.2.2 부터

@GetMapping("/posts")
fun getPosts(pageable: Pageable, assembler:PagedResourcesAssembler<Post>): PagedModel<EntityModel<Post>> {
    val findAll = postRepository.findAll(pageable)
    return assembler.toModel(findAll)
}

자 그럼 이 코드를 테스트할 테스트코드를 작성하자.


@SpringBootTest
@AutoConfigureMockMvc
class PostControllerTest @Autowired constructor(
        val mockMvc: MockMvc,
        val postRepository: PostRepository
){
    @Test
    fun getPosts() {
        createPosts()

        mockMvc.perform(
                get("/posts/")
                        .param("page","3")
                        .param("page","10")
                        .param("sort","created,desc")
                        .param("sort","title"))
                .andDo(print())
                .andExpect(status().isOk)
                .andExpect(jsonPath("$.content[0].title").value("jpa"))
    }

    fun createPosts() {
        var postsCount = 100
        while(postsCount > 0) {
            val post = Post()
            post.title = "jpa"
            postRepository.save(post)
            postsCount--
        }

    }
}

이 테스트코드를 실행하면 무조건 실패한다.

왜냐하면 응답이 이전과는 바뀌었기 때문이다.

이제 HATEOAS가 적용된 응답을 보도록 하자.

{
  "_embedded": {
    "postList": [
      {
        "id": 40,
        "title": "jpa",
        "content": "",
        "created": "2020-06-27T23:48:42.61505",
        "comments": []
      },
    ...
    ...
   ]
  },
  "_links": {
    "first": {
      "href": "http://localhost/posts?page=0&size=20&sort=created,desc&sort=title,asc"
    },
    "prev": {
      "href": "http://localhost/posts?page=2&size=20&sort=created,desc&sort=title,asc"
    },
    "self": {
      "href": "http://localhost/posts?page=3&size=20&sort=created,desc&sort=title,asc"
    },
    "next": {
      "href": "http://localhost/posts?page=4&size=20&sort=created,desc&sort=title,asc"
    },
    "last": {
      "href": "http://localhost/posts?page=4&size=20&sort=created,desc&sort=title,asc"
    }
  },
  "page": {
    "size": 20,
    "totalElements": 100,
    "totalPages": 5,
    "number": 3
  }
}

_embedded에 실제 데이터가 들어오고

링크 정보들이 들어오게 된다.

이게 바로 HATEOAS와 관련된 링크인 것이다.

이 페이지와 관련된 하이퍼링크 정보가 오게 된다.

이 Spring Data Common의 HATEOAS를 사용하면 조금 더 Rest API에 가까운 응답을 만들어낼 수 있게 되는 것이다!

Reference

인프런 백기선님의 스프링 Data JPA



© 2022. by minkuk

Powered by minkuk