Tiven Wang
Wang Tiven July 28, 2017
425 favorite favorites
bookmark bookmark
share share

Leopard

了解更多關於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 的效果。

References

Similar Posts

  • Microservices - Inter-Process Communication The kernal of Microservices Architecture is inter-process communication
  • Microservices - API Gateway : Spring Cloud Gateway Spring Cloud Gateway 是一个新的基于 Spring Framework 5, Project Reactor and Spring Boot 2.0 的 API Gateway 产品
  • Microservices - API Gateway : Zuul Zuul 是来自 NetFlix 的 Microservice 产品家族的 API Gateway 服务或者说是 edge 服务。 Zuul 为开发者构建微服务架构提供了 Routing,Monitoring,Managing resiliency,Security等功能。简单来说,Zuul 可以被看作是一个反向代理,在服务实例间 Zuul 代理内部使用 Eureka server 作为 service discovery,使用Ribbon 作为 load balancing
  • Microservices - Transactions
  • Microservices - API Gateway Implement an API gateway that is the single entry point for all clients. The API gateway handles requests in one of two ways. Some requests are simply proxied/routed to the appropriate service. It handles other requests by fanning out to multiple services.
  • Microservices - Circuit Breaker 访问远程服务时, 比依赖超时时间更好一些的方式是一种叫断路器(Circuit Breaker)的模式. Circuit Breaker 就像一位交通警察, 在前方道路畅通的情况下, 他会放行; 当前方道路由于各种原因拥堵时, 他会告诉你前方道路不通请回; 如果他是个更智能的交警的话, 还会告诉你前方道路部分拥堵, 只允许部分车辆通过, 比如实行单双号.

Comments

Back to Top