了解更多關於HATEOAS的知識請閱讀 Understanding HATEOAS
下載本文完整項目代碼 Github
Setup Dependencies
添加 Spring HATEOAS 的組件:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
Spring Data Commons
Spring Data 的 @EnableSpringDataWebSupport
或者 SpringDataWebConfiguration
會自動發現 Spring HATEOAS 並初始化正確的配置。
Spring Data 提供了一個 ResourceAssembler
接口的實現 PagedResourcesAssembler
,它負責組裝出來 Spring HATEOAS 的 PagedResources
。
@RequestMapping("")
PagedResources<Resource<Hero>> getAll(Pageable pageable, PagedResourcesAssembler<Hero> assembler) {
return assembler.toResource(heroRepository.findAll(pageable));
}
訪問鏈接 http://127.0.0.1:8090/hero?page=1&size=2 可得到如下格式的結果,可以看到它為結果增加了_links
屬性
{
"_embedded": {
"heroList": [
{
"id": "27692676658554722713037360999",
"name": "tiven3"
},
{
"id": "27692676713894954934166015848",
"name": "tiven4"
}
]
},
"_links": {
"first": {
"href": "http://127.0.0.1:8090/hero?page=0&size=2"
},
"prev": {
"href": "http://127.0.0.1:8090/hero?page=0&size=2"
},
"self": {
"href": "http://127.0.0.1:8090/hero?page=1&size=2"
},
"next": {
"href": "http://127.0.0.1:8090/hero?page=2&size=2"
},
"last": {
"href": "http://127.0.0.1:8090/hero?page=2&size=2"
}
},
"page": {
"size": 2,
"totalElements": 5,
"totalPages": 3,
"number": 1
}
}
More HATEOAS
如何對每個 entity 定義其 navigations _links
? 需要對每個entity實現其單獨的ResourceAssembler
首先定義 Entity Hero 對應的 Resource HeroResource
public class HeroResource extends ResourceSupport {
private String name;
...
}
接著定義我們的 HeroAssembler
如下
public class HeroAssembler extends ResourceAssemblerSupport<Hero, HeroResource> {
public HeroAssembler(Class<HeroController> controllerClass, Class<HeroResource> resourceType) {
super(controllerClass, resourceType);
}
@Override
public HeroResource toResource(Hero entity) {
HeroResource resource = createResourceWithId(entity.getId(), entity);
BeanUtils.copyProperties(entity, resource);
return resource;
}
}
接下來就可以為每個 entity 產生對應的 resource 了:
@RequestMapping("/{id}")
HeroResource get(@PathVariable("id") Hero hero) {
return new HeroAssembler(HeroController.class, HeroResource.class).toResource(hero);
}
@RequestMapping("")
PagedResources<HeroResource> getAll(Pageable pageable, PagedResourcesAssembler<Hero> assembler) {
return assembler.toResource(heroRepository.findAll(pageable), new HeroAssembler(HeroController.class, HeroResource.class));
}
訪問鏈接 http://127.0.0.1:8090/hero/27692676658554722713037360999 可以得到想要的效果了
{
"name": "tiven",
"_links": {
"self": {
"href": "http://127.0.0.1:8090/hero/27692676658554722713037360999"
}
}
}
Spring Data Rest
如果你使用了 spring-boot-starter-data-rest
添加 spring-data-rest
依賴的話,它會自動增加對 HATEOAS 的支持。
訪問鏈接 http://127.0.0.1:8090/heros 自動帶有 navigations 的效果。
Comments