restful 风格
HATEOAS是Hypertext As The Engine Of Application State的缩写
REST的最高级形态
该模型把 REST 服务按照成熟度划分成 4 个层次:
该模型将REST划作了由低到高四个等级,等级越高,RESTful就越成熟。
项目中对于RESTful层级的选择要灵活把控,现在最常用的就是level2这个层次。
https://blog.csdn.net/w57685321/article/details/82894803
URI中不应该包含动词。 因为"资源"表示一种实体,所以应该是名词,URI不应该有动词,
动词应该放在HTTP协议中。
举例来说,某个URI是/posts/show/1,其中show是动词,这个URI就设计错了,正确的写法应该是/posts/1,
然后用GET方法表示show。如果某些动作是HTTP动词表示不了的,你就应该把动作做成一种资源。
比如网上汇款,从账户1向账户2汇款500元,错误的URI是:POST /accounts/1/transfer/500/to/2,
正确的写法是把动词transfer改成名词transaction,然后以参数的方式注明其它参数
POST /accounts/transaction?from=1&to=2&amount=500.00
RESTful API最好做到Hypermedia(HATEOAS),即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。
“超媒体即应用状态引擎(hypermedia as the engine of application state)”。
超媒体是什么? 当你浏览Web网页时,从一个连接跳到一个页面,再从另一个连接跳到另外一个页面,就是利用了超媒体的概念: 把一个个把资源链接起来。
要达到这个目的,就要求在表述格式里边加入链接来引导客户端。在《RESTFul Web Services》一书中,作者把这种具有链接的特性成为连通性。
RESTful API最好做到Hypermedia,或HATEOAS,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。比如,当用户向api.example.com的根目录发出请求,会得到这样一个文档。
{"link": {
"rel": "collection https://www.example.com/zoos",
"href": "https://api.example.com/zoos",
"title": "List of zoos",
"type": "application/vnd.yourformat+json"
}}
文档中有一个link属性,用户读取这个属性就知道下一步该调用什么API了。
Hypermedia API的设计被称为HATEOAS。
Github的API就是这种设计,访问api.github.com会得到一个所有可用API的网址列表。
{
"current_user_url": "https://api.github.com/user",
"authorizations_url": "https://api.github.com/authorizations",
// ...
}
从上面可以看到,如果想获取当前用户的信息,应该去访问api.github.com/user,然后就得到了下面结果。
{
"message": "Requires authentication",
"documentation_url": "https://developer.github.com/v3"
}
摘自阮一峰和其它作者博客
默认的Spring使用 HAL render responses
HAL 定义Links 在return的文本中作为性质被包含
使用这种方法可以完成resource discoverability
通过一层一层的json返回数据中的links可以找到所有的资源。
使用spring hateoas能做到restful 第3级的成熟度
HATEOAS 的核心是链接。链接的存在使得客户端可以动态发现其所能执行的动作。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
public class Greeting extends RepresentationModel { // extends ResourceSupport
private final String content;
@JsonCreator
public Greeting(@JsonProperty("content") String content) {
this.content = content;
}
public String getContent() {
return content;
}
}
@RestController
public class GreetingController {
private static final String TEMPLATE = "Hello, %s!";
@RequestMapping("/greeting")
public HttpEntity<Greeting> greeting(
@RequestParam(value = "name", required = false, defaultValue = "World") String name) {
Greeting greeting = new Greeting(String.format(TEMPLATE, name));
greeting.add(linkTo(methodOn(GreetingController.class).greeting(name)).withSelfRel());
return new ResponseEntity<>(greeting, HttpStatus.OK);
}
}
原来的服务器端返回的只是模型类对象本身的内容,并没有提供相关的链接信息。
为了把模型对象类转换成满足 HATEOAS 要求的资源,需要添加链接信息。
Spring HATEOAS 使用 org.springframework.hateoas.Link 类来表示链接。
Link 类遵循 Atom 规范中对于链接的定义,包含 rel 和 href 两个属性。
属性 rel 表示的是链接所表示的关系(relationship),
href 表示的是链接指向的资源标识符,一般是 URI。
资源通常都包含一个属性 rel 值为 self 的链接,用来指向该资源本身。
在创建资源类时,可以继承自 Spring HATEOAS 提供的 org.springframework.hateoas.Resource 类,
Resource 类提供了简单的方式来创建链接。
这里使用的是ResourceSupport类,Resource继承的ResourceSupport类,它们功能类似。
@JsonCreator就是如果JavaBean没有缺省构造方法,@JSONCreator可以用来指定构造方法来创建Java对象
@JsonProperty此注解用于属性上,作用是把该属性的名称序列化为另外一个名称,如把trueName属性序列化为name,
@JsonProperty(“name”)
{
"content": "Hello, World!",
"_links": {
"self": {
"href": "http://localhost:8080/greeting?name=World"
}
}
}