[Spring JPA #19] 스프링 데이터 HATEOAS

| 스프링 데이터 HATEOAS


HATEOAS에 대한 설명은 아래 링크로 대신하겠습니다.


[Spring/Spring Boot] - [Spring Boot #19] 스프링 부트 Spring HATEOAS


| 스프링 데이터 HATEOAS 예제


프로젝트 구조

├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │   └── tutorial
│   │   │   └── springevent
│   │   │   ├── Application.java
│   │   │   ├── PostController.java
│   │   │   ├── Post.java
│   │   │   └── PostRepository.java
│   │   └── resources
│   │   └── application.properties
│   └── test
│   └── java
│   └── com
│   └── tutorial
│   └── springevent
│   └── PostControllerTest.java

의존성 관리

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

소스 코드

@SpringBootApplication
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@Entity
@Data
public class Post {

@Id @GeneratedValue
private Long id;

private String title;

@Temporal(TemporalType.TIMESTAMP)
private Date created;
}
public interface PostRepository extends JpaRepository<Post, Long> {
}
@RestController
public class PostController {

@Autowired
PostRepository postRepository;

@GetMapping("/posts")
public PagedResources<Resource<Post>> getPosts(Pageable pageable, PagedResourcesAssembler<Post> assembler) {
return assembler.toResource(postRepository.findAll(pageable));
}
}
  • PageResource는 Pageable한 객체의 집합을 나타냅니다. 따라서 이 객체는 Pageable한 객체를 모아서 전달하는 DTO역할을 하게 됩니다.
  • PageResourcesAssembler는 Page 객체들을 손쉽게 PagedResources 객체로 변환해주는 작업을 수행합니다.


테스트 코드

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class PostControllerTest {

@Autowired
MockMvc mockMvc;

@Autowired
PostRepository postRepositry;

@Test
public void getPosts() throws Exception {
createPosts();

mockMvc.perform(get("/posts/")
.param("page", "3")
.param("size", "5")
.param("sort", "created,desc")
.param("sort", "title"))
.andDo(print())
.andExpect(status().isOk());
}

private void createPosts() {
int postsCount = 20;
while(postsCount > 0) {
Post post = new Post();
post.setTitle("jpa");
post.setCreated(new Calendar.Builder().
setDate(2019, 2, 1)
.build()
.getTime());
postRepositry.save(post);
postsCount--;
}
}
}
  • 위 테스트 코드에서는 page를 20개 생성한 다음 그 페이지에 대한 정보를 mockMvc를 이용하여 테스트하는 코드입니다. page는 3페이지 사이즈는 5인 데이터를 수신받게 되고 HATEOAS로 구현한 Rest API는 다음과 같은 정보를 넘겨 줍니다.
{
"_embedded": {
"postList": [
{
"id": 9,
"title": "jpa",
"created": null
},
{
"id": 17,
"title": "jpa",
"created": null
},
{
"id": 7,
"title": "jpa",
"created": null
},
{
"id": 8,
"title": "jpa",
"created": null
},
{
"id": 6,
"title": "jpa",
"created": null
}
]
},
"_links": {
"first": {
"href": "http://localhost/posts?page=0&size=5&sort=created,desc&sort=title,asc"
},
"prev": {
"href": "http://localhost/posts?page=2&size=5&sort=created,desc&sort=title,asc"
},
"self": {
"href": "http://localhost/posts?page=3&size=5&sort=created,desc&sort=title,asc"
},
"last": {
"href": "http://localhost/posts?page=3&size=5&sort=created,desc&sort=title,asc"
}
},
"page": {
"size": 5,
"totalElements": 20,
"totalPages": 4,
"number": 3
}
}
  • HATEOAS를 적용하지 않았을 때는 단순히 페이지 정보만 넘겨주는 응답이 돌아오지만 적용했을 때는 Page에 대한 정보와 더불어 이 Page에 대한 정보로 무엇을 할 지에 대한 것을 _link를 통해서 넘겨줍니다. 이 정보를 가지고 클라이언트 단에서 이 정보들을 가지고 어떤 요청을 해야할 지에 대한 것을 손쉽게 핸들링할 수 있습니다.


https://www.inflearn.com/course/스프링-데이터-jpa


이 글을 공유하기

댓글(0)

Designed by JB FACTORY