rest 的理解

rest:表现层状态转移。

什么是restful协议?https://en.wikipedia.org/wiki/Representational_state_transfer 使用restful的好处。

Rest是一种体系结构样式,他定义了一组用于创建web服务的约束。符合REST体系结构风格或RESTful Web服务的Web服务提供Internet上计算机系统之间的互操作性。与rest兼容的web服务允许请求系统通过使用统一的和预定义的无状态操作集来访问和操作web资源的文本表示。其他类型的web服务,如SOAP web服务,公开它们自己的任意操作集。

“Web资源”最初在万维网上定义为由url标识的文档或文件。然而,现在它们有了一个更加通用和抽象的定义,它包含了所有可以在web上以任何方式识别、命名、处理或处理的事物或实体。在基于rest的web服务中,对资源URI的请求将通过HTML、XML、JSON或其他格式的有效负载引发响应。响应可以确认对存储的资源进行了一些更改,并且响应可以提供到其他相关资源或资源集合的超文本链接。当使用HTTP时,最常见的操作是GET、POST、PUT、DELETE和其他预定义的CRUD HTTP方法。

通过使用无状态协议和标准操作,REST系统旨在通过重用可管理和更新的组件来实现快速性能、可靠性和增长能力,即使在系统运行时也不影响整个系统。

表征状态转移(rest)一词是由Roy Fielding在2000年的博士论文中提出并定义的。从1994年开始,Fielding的论文解释了REST原则,即“HTTP对象模型”,并被用于设计HTTP 1.1和统一资源标识符(Uniform Resource identifier, URI)标准。[4][5][6]这个词是为了唤起的形象设计良好的Web应用程序的行为:它是一个网络的网络资源(虚拟状态机),用户通过应用程序通过选择链接,如/ user /汤姆,和获取或删除等操作(状态转换),导致下一个资源(代表应用程序的下一个状态)传输给用户使用。

1建筑属性

REST架构风格的约束影响以下架构属性:

组件交互中的性能,这是影响用户感知性能和网络效率的主要因素

可伸缩性允许支持大量组件和组件之间的交互。Roy Fielding将REST对可伸缩性的影响描述如下:rest的客户机-服务器关注点分离简化了组件实现,降低了连接器语义的复杂性,提高了性能调优的有效性,并提高了纯服务器组件的可伸缩性。分层系统约束允许中介——代理、网关和防火墙——在通信的各个点引入,而无需更改组件之间的接口,从而允许它们帮助通信转换或通过大规模共享缓存提高性能。REST通过将消息约束为自描述的方式实现了中间处理:请求之间的交互是无状态的,标准方法和媒体类型用于指示语义和交换信息,响应显式地指示可缓存性。

统一接口的简单性;

组件的可修改性以满足不断变化的需求(甚至在应用程序运行时);

服务代理之间组件间通信的可见性;

利用数据移动程序代码实现组件的可移植性;

在组件、连接器或数据中存在故障时,在系统级别对故障的抵抗的可靠性。

2体系结构约束

六个指导约束定义了一个RESTful系统。这些约束限制了服务器处理和响应客户机请求的方式,因此,通过在这些约束中操作,服务可以获得理想的非功能属性,如性能、可伸缩性、简单性、可修改性、可见性、可移植性和可靠性。如果服务违反了任何必需的约束,就不能认为它是RESTful的。

形式REST约束如下:

客户机-服务器体系结构

客户机-服务器约束背后的原则是关注点分离。将用户界面关注与数据存储关注分离可以提高用户界面跨多个平台的可移植性。它还通过简化服务器组件来提高可伸缩性。然而,对Web来说最重要的可能是分离允许组件独立地演进,从而支持多个组织领域的internet规模需求

无国籍(无状态协议

客户机-服务器通信受到请求之间服务器上没有存储客户机上下文的约束。来自任何客户机的每个请求都包含服务请求所需的所有信息,会话状态保存在客户机中。服务器可以将会话状态转移到另一个服务(如数据库),以便在一段时间内保持持久状态并允许身份验证。客户端在准备转换到新状态时开始发送请求。当一个或多个请求未完成时,客户端被认为处于过渡状态。每个应用程序状态的表示都包含可在下次客户端选择发起新的状态转换时使用的链接。

缓存能力

在万维网上,客户机和中介体可以缓存响应。因此,响应必须隐式或显式地将自己定义为可缓存的或不可缓存的,以防止客户机在响应进一步请求时获取陈旧或不合适的数据。管理良好的缓存部分或完全消除了一些客户机-服务器交互,进一步提高了可伸缩性和性能。

可缓存:

        HTTP状态码(org.springframework.http.HttpStatus)

             200:HttpStatus#ok

             304:HttpStatus#NOT_MODIFIED  第一次完整请求,获取响应头(200),body直接获取,第二次请求,只读取头信息,响应头(304),客户端(浏览器)取上次body结果。

             400:HttpStatus#BAD_REQUEST

              ....

       响应:

              响应头(Headers)

                     元信息(Meta-Data)

                             Accept-Language->Locale

                            Connection->Keep-Alive

                            实现多值Map:MutiValueMap

                                    key:value=1:n

                                    name:value=1:n

             响应体

                    业务信息(Business Data)

                    Body:HTTP实体、REST

                            @ResponseBody

                             HttpEntity.body属性(泛型结构)

                   Payload:消息JMS、事件、SOAP

 

                    

image2019-7-21%2023%3A42%3A20.png?version=1&modificationDate=1563724752000&api=v2

 

分层系统

客户端通常无法分辨它是直接连接到终端服务器,还是一路连接到中介。中介服务器可以通过启用负载平衡和提供共享缓存来提高系统的可伸缩性。它们还可以执行安全策略。

按需编码(可选)

参见:客户端脚本

服务器可以通过传输可执行代码临时扩展或定制客户机的功能。例如,编译组件(如Java applet)和客户端脚本(如JavaScript)。

3统一的接口

统一接口约束是任何REST服务设计的基础。它简化和解耦了体系结构,使每个部分能够独立发展。这个统一接口的四个约束条件是:

请求中的资源标识:即自定义消息

在请求中标识单个资源,例如在基于web的REST系统中使用uri。资源本身在概念上与返回给客户机的表示是分开的。例如,服务器可以从数据库中以HTML、XML或json的形式发送数据——这些都不是服务器的内部表示。

通过表示操作资源----http动词

当客户机持有资源的表示形式(包括附加的任何元数据)时,它有足够的信息来修改或删除资源。

自描述信息

每个消息都包含足够的信息来描述如何处理消息。例如,可以通过媒体类型指定要调用的解析器

       注解驱动

              @RequestBody

               JSON-> MappingJackson2HttpMessageConverter

               @ResponseBody

                JSON->MappingJackson2HttpMessageConverter

       接口编程

              ResponseEntity extends HttpEntity

              RequestEntity extends HttpEntity

 

超媒体作为应用程序状态(HATEOAS)的引擎

访问了REST应用程序的初始URI(类似于人工Web用户访问Web站点的主页)之后,REST客户机应该能够动态地使用服务器提供的链接来发现它所需的所有可用操作和资源。随着访问的继续,服务器将使用文本进行响应,其中包括指向当前可用的其他操作的超链接。客户端不需要硬编码有关REST服务的结构或动态的信息。

应用于Web服务

遵循REST体系结构约束的Web服务api称为RESTful api。基于http的RESTful api的定义如下

一个基本URL,例如http://api.example.com/resources;

定义状态转换数据元素(例如,Atom、微格式、应用程序/vnd)的媒体类型。当前表示告诉客户端如何组合转换到所有下一个可用应用程序状态的请求。这可以像URL一样简单,也可以像Java applet一样复杂

标准HTTP方法(例如,选项、GET、PUT、POST和DELETE)

URL和HTTP方法之间的关系

下表显示了在RESTful API中通常如何使用HTTP方法:

HTTP方法

Get、put、patch、Post、delete

GET方法是一种安全的方法(或无效),这意味着调用它不会产生副作用:检索或访问记录不会改变它。PUT和DELETE方法是等幂的,这意味着无论重复请求多少次,API公开的系统状态都是不变的。

与基于soap的Web服务不同,RESTful Web api没有“官方”标准。这是因为REST是一种体系结构风格,而SOAP是一种协议。REST本身不是标准,但是RESTful实现使用了标准,例如HTTP、URI、JSON和XML。许多开发人员还将他们的api描述为RESTful,尽管这些api实际上并没有实现上面描述的所有架构约束(尤其是统一接口约束)

        资源定位-URI

        资源操作-HTTP动词

                GET

                         @GetMapping

                                   注解属性别名和覆盖:在Spring framework4.2中引入,Spring Boot1.3才能使用,Spring Boot加以发展,可以看一下AnnotatedElementUtils.getMergedAnnotationAttributes

                                   根据这个,可以自己实现类似的注解,比如:

                    fc6b920670d4bab3c9aade251a33e7882e8.jpg

                PUT

                         @PutMapping

                POST

                         @PostMapping

                        @PostMapping是注解,@RequestMapping是@PostMapping的注解:

                                     @RequestMapping是@PostMapping的元注解

                                     @RequestMapping元标注了@PostMapping

                                     @AliasFor只能标注在目标注解的属性,所annotation()的注解必须是元注解,该注解attribute必须是是元注解的属性。

8e487380c1d652db33a107cb3cf45d596dc.jpg

 

                PATCH

                         @PatchMapping

                         限制,在Servlet API中并没有规定PATCH方法,Spring Web对其做了扩展。

 

javax.servlet.http.HttpServlet

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String method = req.getMethod();
 long lastModified;
 if (method.equals("GET")) {
        lastModified = this.getLastModified(req);
 if (lastModified == -1L) {
            this.doGet(req, resp);
 } else {
            long ifModifiedSince;
 try {
                ifModifiedSince = req.getDateHeader("If-Modified-Since");
 } catch (IllegalArgumentException var9) {
                ifModifiedSince = -1L;
 }

            if (ifModifiedSince < lastModified / 1000L * 1000L) {
                this.maybeSetLastModified(resp, lastModified);
 this.doGet(req, resp);
 } else {
                resp.setStatus(304);
 }
        }
    } else if (method.equals("HEAD")) {
        lastModified = this.getLastModified(req);
 this.maybeSetLastModified(resp, lastModified);
 this.doHead(req, resp);
 } else if (method.equals("POST")) {
        this.doPost(req, resp);
 } else if (method.equals("PUT")) {
        this.doPut(req, resp);
 } else if (method.equals("DELETE")) {
        this.doDelete(req, resp);
 } else if (method.equals("OPTIONS")) {
        this.doOptions(req, resp);
 } else if (method.equals("TRACE")) {
        this.doTrace(req, resp);
 } else {
        String errMsg = lStrings.getString("http.method_not_implemented");
 Object[] errArgs = new Object[]{method};
 errMsg = MessageFormat.format(errMsg, errArgs);
 resp.sendError(501, errMsg);
 }

}

 

image2019-7-21%2023%3A58%3A20.png?version=1&modificationDate=1563724752000&api=v2

 

                DELETE

                         @DeleteMapping

 

根据别名覆盖和这几个注解,我们可以尝试写一个组合注解,把2个注解的功能结合起来,比如:

ec3a543cc99e6f6f78168e7feb62791bc45.jpg

c4a4592349de423460cea4f185f88a6028d.jpg

8ad9153ac28a3f18cb66fec17df713fe2b2.jpg

d22bdc1e1fad343a1cc223c84dbea8f37b3.jpg

以上还可以对事务起个别名:

c97d475ea8e218dc751c506a7b4692b9384.jpg

a281e8d233efb61632176dd09d197a9e32a.jpg

7cfe0ae2e9f4145e9dab1412d26cc62b22a.jpg

f19cd1eb1e40402e82e23ea5a70f3621b23.jpg

 

 

071fd316603890a16c24e9fb357bc946c00.jpg

762765d27be07ffb727945322e246de8fc5.jpg

 

 

转载于:https://my.oschina.net/u/3944601/blog/3077093

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值