RESTful levels & HATEOAS

  1. 什么是RESTful

Fielding在论文中将REST定位为“分布式超媒体应用(Distributed Hypermedia System)”的架构风格,它在文中提到一个名为“HATEOAS(Hypermedia as the engine of application state)”的概念。

HATEOAS又是什么鬼?

我们知道REST是使用标准的HTTP方法来操作资源的,但仅仅因此就理解成带CURD的Web数据库架构就太过于简单了。 这种说法忽略了一个核心概念: “超媒体即应用状态引擎(hypermedia as the engine of application state)”。<u> 超媒体是什么? 当你浏览Web网页时,从一个连接跳到一个页面,再从另一个连接跳到另外一个页面,就是利用了超媒体的概念: 把一个个把资源链接起来。</u>
要达到这个目的,就要求在表述格式里边加入链接来引导客户端。在《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了。rel表示这个API与当前网址的关系(collection关系,并给出该collection的网址),href表示API的路径,title表示API的标题,type表示返回类型。
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"
}
以上内容都摘自阮一峰和其它作者博客,如有冒犯,请及时告知
我当时第一眼看到HATEOAS也是一脸懵逼,因为在Spring依赖中看到过这个词,所以就留意了一下。其实在我看来,HATEOAS是符合RESTful规范的一个方面,客户端在消费RESTful服务的时候,出了得到资源本身以外,还可以得到一些相关其他信息,比如,其他相关链接,返回类型等等。

2.构建RESTful服务最佳实践

  • 第一条也是最容易犯错的:<u>URI中不应该包含动词</u>。 因为"资源"表示一种实体,所以应该是名词,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方法,使得用户不查文档,也知道下一步应该做什么。
  • 其它需要注意的地方参见文末贴出的链接

下面重头戏来了:

3.使用SpringBoot构建符合Hypermedia规范的RESTful 服务

我以后每次都要说一遍:SpringBoot框架是所有Java开发者的福音
在SpringBoot中构建符合Hypermedia规范的RESTful 服务简单到不能再简单-----只需要添加一条依赖:

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>

添加一个简单的领域类:

@Entity
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    private String firstName;
    private String lastName;

    //getter and setter
}

以及一个dao层接口:

//@RepositoryRestResource(collectionResourceRel = "people",path="people")
public interface PersonRepository  extends PagingAndSortingRepository<Person,Long>{
    List<Person> findByLastName(@Param("name") String name);
}

注释掉的标签可选,主要是在只用RESTful的时候可以改变URI,比如,加上此处就把/person变成/people

一切都和我们正常开发web没啥区别,但是现在,见证奇迹的时刻到了:

1.GET localhost:8080
返回:

{
    "_links":{
        "people":{
            "href": "http://localhost:8080/people{?page,size,sort}",
            "templated": true
        },
        "profile":{
            "href": "http://localhost:8080/profile"
        }
    }
}

上面的返回中包括了people这个资源的链接明确指出了我们可以用类似http://localhost:8080/people?page=1&size=10&sort=firstname这样的方式请求资源。

2.增加一个people资源:POST localhost:8080/people,请求数据用json{ "firstName" : "李", "lastName" : "雷" }
返回:

{
    "firstName": "李",
    "lastName": "雷",
    "_links":{
        "self":{
            "href": "http://localhost:8080/people/5"
        },
        "person":{
            "href": "http://localhost:8080/people/5"
        }
    }
}

返回信息中出了新加入信息的各个字段,还有一个href链接指向它--这是合乎情理的,客户端总是想要看看新加入的这条信息长什么样,从这个角度说,这条返回信息还是很贴心的。
3.GET localhost:8080/people/

{
    "_embedded":{
        "people":[
            {
                "firstName": "李",
                "lastName": "雷",
                "_links":{"self":{"href": "http://localhost:8080/people/5" }, "person":{"href": "http://localhost:8080/people/5"…}
            }
        ]
    },
    "_links":{
        "self":{
            "href": "http://localhost:8080/people"
        },
        "profile":{
            "href": "http://localhost:8080/profile/people"
        },
        "search":{
            "href": "http://localhost:8080/people/search"
        }
    },
    "page":{
        "size": 20,
        "totalElements": 1,
        "totalPages": 1,
        "number": 0
    }
}

返回一个people列表,包含所有数据
page标签的出现,是由于我们的repository继承了PagingAndSortingRepository接口
search标签的出现,是由于我们的repository声明了一个方法,List<Person> findByLastName(@Param("name") String name);这个方法可以像search标签描述的那样调用:http://localhost:8080/people/search/findByLastName{?name},示例:http://localhost:8080/people/search/findByLastName?name=雷

4.PUT localhost:8080/people/5,json:{ "firstName" : "李", "lastName" : "小雷" }

{
    "firstName": "李",
    "lastName": "小雷",
    "_links":{
        "self":{
            "href": "http://localhost:8080/people/5"
        },
        "person":{
            "href": "http://localhost:8080/people/5"
        }
    }
}

资源被正确更新
5.PATCH localhost:8080/people/5,json:{ "lastName" : "大雷" }

{
    "firstName": "李",
    "lastName": "大雷",
    "_links":{
        "self":{
            "href": "http://localhost:8080/people/5"
        },
        "person":{
            "href": "http://localhost:8080/people/5"
        }
    }
}

原文地址:https://www.cnblogs.com/dpqq/p/10732511.html

时间: 2024-11-07 11:35:18

RESTful levels & HATEOAS的相关文章

Restful levels&amp;HATEOAS

RESTful: Rest是一种软件架构风格.设计风格,而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制.而满足这些约束条件和原则的应用程序或设计就是 RESTful. 如图有四个层次: level 0:The swarmp of POX(Plain old XML) 该模型的出发点是使用HTTP作为远程交互的传输系统,但不使用Web的任何机制.基本上你在这里做的是使用HTTP作为你自己的远程交互

RESTful levels、HATEOAS

概述: REST(英文:Representational State Transfer,简称REST)描述了一个架构样式的网络系统,比如 web 应用程序.它首次出现在 2000 年 Roy Fielding 的博士论文中,Roy Fielding是 HTTP 规范的主要编写者之一.在目前主流的三种Web服务交互方案中,REST相比于SOAP(Simple Object Access protocol,简单对象访问协议)以及XML-RPC更加简单明了,无论是对URL的处理还是对Payload的编

RESTful level &amp; HATEOAS

RESTful: Rest是一种软件架构风格.设计风格,而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制.而满足这些约束条件和原则的应用程序或设计就是 RESTful. 如图有四个层次: level 0:The swarmp of POX(Plain old XML) 该模型的出发点是使用HTTP作为远程交互的传输系统,但不使用Web的任何机制.基本上你在这里做的是使用HTTP作为你自己的远程交互

Introduction of RESTful level &amp; HATEOAS

REST level 0级传统的RPC,基于SOAP的WS,调用的服务名,参数放在HTTP协议的body里面,同时必须以POST方式提交,问题在于你必须清楚的知道所有服务,子服务,及其参数的信息,并且需要知道各种服务的不同点 1级利用resource概念,把所有服务都抽取成resource概念,从body中提取到header里,这样做的好处就是如果你知道一个服务地址,你可能无需知道具体服务是什么,依照资源的惯例就访问到服务,比如/books/1 2级利用HTTP动词,HTTP定义了4种动词,GE

Rest与RestFul

1.Rest是什么 Roy Thomas Fielding博士是HTTP和URI等Web架构标准的主要设计者,Apache HTTP服务器的主要开发者.他在他的博士论文里提出了“架构风格”这个软件领域的专业术语,推导出一个称为“REST”的架构风格,并详细阐述了REST架构风格的推倒过程,指出不同架构的评价标准就是其背后的的架构风格.值得注意的是,REST指的是一种架构风格的名称,这里的风格,不同于我们通常所说的个性化的含义,它代表的一组特征,在软件领域我们把它叫做架构约束. 2.Rest与Re

深入浅出:5G和HTTP

本文将会讲到5G和HTTP.曾经在深入浅出经典面试题:从浏览器中输入URL到页面加载发生了什么 - Part 3 提到为什么有些RPC框架不选用HTTP,而5G会采用HTTP. 您可以从本文里获取到一些概念:5G用HTTP作为reference point interface的实现,HTTP/2,RESTful API/HATEOAS/OpenAPI等最佳实践和标准,这些都是一些常见但是又容易忽略的知识点. 本文参考了一些文章,见文章末尾的链接列表. HTTP的优点和缺点 我们大家知道HTTP协

[翻译]Restful Web服务模型

最近我一直在阅读"Rest实践"的草稿:一本几位同事一直在努力编写的书. 他们的目的是解释如何使用Restful Web服务来处理企业面临的许多集成问题. 这本书的核心在于这样一种观点,Web以一个有效的可扩展分布式系统存在,它的工作效果非常好,这足以证明我们可以从中得到想法轻松地构建集成系统. 图1: REST的步骤 为了帮助解释一个web-style的系统的具体属性,作者使用了由Leonard Richardson开发的一种restful成熟度模型,这模型他在QCon谈话中解释过.

RESTful最佳实践

哲学 不要为了RESTful而RESTful 在能表达清楚的情况下,简单就是美 接口路径设计 接口设计原则 URI指向的是唯一的资源对象 示例: 指向ID为yanbo.ai的Account对象 GET http://~/$version/accounts/yanbo.ai URI可以隐式指向唯一的集合列表 示例: 隐式地指向trades list 集合 GET http://~/$version/trades/(list)等同于GET http://~/$version/trades 聚合资源必

[CI] 使用CodeIgniter框架搭建RESTful API服务

在2011年8月的时候,我写了一篇博客<使用CodeIgniter框架搭建RESTful API服务>,介绍了RESTful的设计概念,以及使用CodeIgniter框架实现RESTful API的方法.转眼两年过去了,REST在这两年里有了很大的改进.我对于前一篇博客中的某些方面不是很满意,所以希望能利用这次机会写一个更加完善的版本.我的项目基于Phil Sturgeon的CodeIgniter REST Server,遵循他自己的DBAD协议.Phil的这个项目很棒,干净利落,简单实用,并