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 - 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 就像一位交通警察, 在前方道路畅通的情况下, 他会放行; 当前方道路由于各种原因拥堵时, 他会告诉你前方道路不通请回; 如果他是个更智能的交警的话, 还会告诉你前方道路部分拥堵, 只允许部分车辆通过, 比如实行单双号.
  • Microservices - Architecture Microservice architecture (MSA) is an approach to building software systems that decomposes business domain models into smaller, consistent, bounded-contexts implemented by services. These services are isolated and autonomous yet communicate to provide some piece of business functionality. Microservices are typically implemented and operated by small teams with enough autonomy that each team and service can change its internal implementation details (including replacing it outright!) with minimal impact across the rest of the system.
  • Microservices - Load Balancing 在微服务架构中每个服务都可能有多个运行实例, 那么服务消费者在调用服务时怎么定位应该把请求发送给哪个实例呐? 这就是负载均衡 Load Balancing 要做的事情。Load Balancing 可以在服务端也可以是在消费端。
  • Microservices - Service Discovery Clients of a service use either Client-side discovery or Server-side discovery to determine the location of a service instance to which to send requests. Why use Service Discovery?
  • Try Cloud Foundry 10 - Service Discovery Service Registry for Pivotal Cloud Foundry (PCF) provides your applications with an implementation of the Service Discovery pattern, one of the key tenets of a microservice-based architecture. Trying to hand-configure each client of a service or adopt some form of access convention can be difficult and prove to be brittle in production. Instead, your applications can use the Service Registry to dynamically discover and call registered services.

Comments

comments powered by Disqus
Back to Top