1. 使用ASP.NET Core 3.x 构建 RESTful API - 1.准备工做javascript
REST一词最先是在2000年,由Roy Fielding在他的博士论文《Architectural Styles and the Design of Network-based Software Architecture》中提出的。他在本文中创造了REST这个术语。这篇论文的地址是:https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm。 html
REST的全称是 Representational State Transfer(状态表述转换)。这个词表面看起来可能不太好理解。但其实REST就是勾画出了这样一幅景象,它描述了Web应用到底怎么样设计才算是优良的。这里定义了如下三点: java
一组网页的网络(一个虚拟状态机); json
在这些网页上,用户能够经过点击连接来前进(状态转换); api
点击连接的结果就是下一个网页(表示程序的下一个状态)被传输到用户那里,并渲染好给用户使用。 浏览器
论文中还提到,REST是一种为分布式超媒体系统所用的架构风格,也就是说,REST定义了一种架构风格来帮助建立和组织出更好的分布式系统。这里的关键词是架构风格。 缓存
归纳的说: 服务器
REST是一种架构风格,而不是规范或标准; 网络
REST须要使用一些规范、协议或标准来实现这种架构风格; 架构
REST与协议无关。JSON并非REST强制的,甚至HTTP都不是REST强制使用的,但这也仅仅是从理论上来看。
REST背后的主要思想就是:采用RESTful架构风格进行组织的分布式系统,将在如下几个方面获得改善:
性能。REST的通讯风格应该是简单而且高效的,采用它的系统性能应该得以提高。
组件交互的可扩展性。其实任何分布式系统都容许这种扩展性,而REST所提出的简单交互方式更是如此。
组件的可修改性。分布式系统的分布式本质和REST提出的关注点分离,使得组件得以以最小的成本和最低的风险彼此独立的进行修改。
可移植性。REST与技术和语言无关,因此使用任何技术均可以实现REST。
可靠性。REST所提出的无状态约束容许在系统发生故障后轻松的恢复系统。
可视性。REST所提出的无状态约束为所述请求添加了完整的状态(一会再解释)。
从上面这个列表,咱们能够看出,一个以组件为中心设计的系统很是容易出错,若是一个组件出现了故障而不影响整个系统的稳定性,那这样对任何系统都是极有好处的。对组件进行互联是很是简单的,可是须要在添加新特性或扩大缩小规模时将风险降至最低。凭借REST的可移植性,使用REST思想进行设计的系统能够为更普遍的受众使用。经过通用的接口,系统能够被更普遍的开发者所使用。为了实现这些属性和好处,REST使用一组约束来帮助定义统一的接口。
为了定义REST架构,首先要定义出一个空无的状态,也就是一个没有任何约束的系统。在这里,组件之间的差别就是个迷,而后咱们再一个挨一个的往里面添加约束并保证这些约束能够互不干扰、融洽相处。这些约束都定义了实现REST API的框架应该如何被构建和设计。下面就介绍一些这六个约束:
客户端-服务器:关注点分离是这个约束的核心主题。整个Web系统是一个基于客户端-服务端的系统,客户端和服务端彼此独立(独立实现和部署等),并扮演着不一样的角色。它们可使用不一样的语言、技术或平台,并能够独自进化,只要它们都听从Web的统一接口便可。
无状态:无状态表示Web服务器不被要求记住客户端程序的状态,由于这个缘由,客户端在发送请求的时候必须包含全部可能须要的相关信息,也就是说状态须要被包含在请求里,同时也说明客户端须要维护本身的状态。因为维护状态的工做由客户端本身来完成了,因此服务器就节省了不少服务器资源,这样服务器就能够为更多的客户端服务。
统一的资源接口/界面:Web组件之间的交互就意味着客户端、服务端以及基于网络的中介程序都依赖于它们接口的统一性(API和API的消费者之间共用相同标准的一套接口)。Web组件能够在统一接口的四个约束条件下一致的进行互操做。这四个约束是:
资源的标识:针对RESTful Web API而言,就是指URI,只有获得这个资源标识,才有可能找到该资源并对该资源进行操做。可是从概念上来说,资源和它的表述是分开的。例如,咱们经过一个URI找到了服务端的Company这个资源,可是咱们获得的Company这个资源的表述和服务端的Company是不同的,由于咱们获得的是JSON格式(大多数状况)的Company数据。同时还有媒体类型(media type)对其进行描述,例如application/json等。若是请求的是xml格式的数据,那么咱们一般会获得xml格式表述的数据。因此同一个资源获得的表述也多是不一样的(例如JSON vs Xml)。
经过表述来对资源进行操纵:REST的组件对资源的操做(CRUD)是经过首先获取该资源现有的表述或者目标表述,而后在组件之间完成从现有表述到目标表述的转换。换句话讲,当客户端拥有资源表述的时候(包括可能的元数据),那么它就应该拥有足够的信息来修改或者删除服务器上的资源,前提是客户端须要有这些权限。例如,我从服务器获取到了Company的资源响应(包括元数据)以后,凭借这些信息客户端就应该能够成功的删除或修改这个Company的资源数据了。但这又是怎么实现的呢?若是服务器上的Company API支持对Company进行删除或者修改,那么在咱们获取(GET)到这个Company资源的响应后,响应里面应该包含着删除或者修改这个Company资源的URI,经过这些URI客户端就能够完成相应的操做。
带有自我描述的信息:因为REST是无状态的(没有会话机制),因此发送REST请求的时候,必须把全部相关的信息随着请求一块儿发送到服务器端。换句话说,须要经过使用元数据或者其它方式,让REST的请求中包含的数据必须带有“自我描述”性的信息,以便让对方知道如何处理该请求。
超媒体做为应用程序状态的引擎(HATEOAS):REST架构风格中,客户端是经过超媒体与服务器端动态提供的一个“应用网络”来进行交互的。这里要求在首次进入REST网络时有第一个连接,还要求客户端必须具有处理超媒体内容的能力。除此以外REST对客户端来讲再无其它要求。这是书上给出的解释。举个例子,本文第二段中提到用户经过点击网页中的连接来进行跳转的时候,浏览器的状态就变化了。这些连接就是超文本,而超媒体就是超文本的泛化。针对API来讲,它就是程序状态的引擎。换句话说,超媒体会驱动如何消费和使用API,它会告诉API消费者使用这些API能作什么,例如:能删除这个资源吗?能修改资源吗?如何能建立这种资源?从哪能获取这个资源?最终,它还容许自包含文档的API。
多层系统:REST的解决方案适用于多层架构,这些层能够被修改,能够被添加或删除,能够是物理的,也能够是逻辑的。每一层只能够看到和它相邻的上一层或下一层,其它非相邻层的结构它彻底看不到。这也说明客户端没法得知它链接的是架构最终层仍是链接到了某个中间层。因此REST仅仅知道一个层,也就是对外那一层,由于这个缘由,整个系统的复杂性获得了控制,由于能够对任何局部的层次进行替换,而不至于影响整个系统。
可缓存:每一个响应信息必须明确的指出它是否能够被缓存。缓存响应数据能够减小客户端感知的响应时间,提升总体的可用性和可靠性,并控制整个Web服务器的负载。客户端也能够在实时性和响应速度之间作出选择,以便服务器端相应的决定是从缓存仍是从最终信息源哪里得到服务响应的内容。
按需编码(可选约束):它描述了服务器能够扩展或者定制客户端的功能。例如若是客户端是一个Web应用,那么服务器端能够发送一些javascript脚本给客户端,以扩展客户端的功能。可是这也形成了客户端和服务器端之间的技术耦合,由于客户端必须能都懂得服务器端发过来的代码,因此这个约束是可选的。
这些就是REST的约束,而没有实现这些约束的Web API就不是RESTful API,因此如今见到的不少RESTful API并非真的RESTful API,可是这也不能说明这些API就很差,只不过针对那些没有实现的约束可能要作出一些权衡取舍,付出一些代价。
这个成熟度模型是由Leonard Richardson所提出的,这个模型是用来评价API的成熟度。它的结果分为0,1,3,4共四个级别。咱们一个一个看。
Level 0,POX(Plain old xml)沼泽。它描述了API仅仅是使用HTTP协议来作远程交互,而HTTP协议的其他部分都是瞎用的,有时用出了RPC的风格(例如SOAP, 尤为是使用WCF的时候)。例以下面这个程序都是在同一个URI上面进行读取资源和建立资源的:
换句话说,就是使用HTTP协议做为一种传输方式而已,没有什么规矩可言。
Level 1,资源。在这级里, 与Level 0不一样,每一个资源都映射到本身的URI上了, 可是HTTP方法并无正确的使用, 可是仍是下降了一些复杂度。例以下面这个例子使用了不一样的URI,可是HTTP方法使用的都是POST:
Level 2,动词。正确使用了HTTP动词,例如GET、POST、DELETE、PUT、PATCH等等都是按照协议的意图正确的使用了。状态码也正确的使用了,例如200表示成功,201表示建立成功等等。这也符合了统一资源接口/界面这个约束。从软件开发角度,这也去掉了没必要要的变种,由于咱们使用一样的动词来作同类的事情。例如:
Level 3,超媒体。这意味着,API支持HATEOAS(超媒体做为应用状态的引擎, Hypermedia as the Engine of Application State),这也是统一资源接口/界面约束里面的一条。例如:
这个GET请求的响应除了包含数据以外,还包含连接(超媒体),这些连接能够驱动应用程序的状态。从软件开发的角度讲,就是引入了可发现性和自包含文档。
根据Roy Fielding博士的描述,达到Level 3也仅仅是RESTful API的一个前提。也就是说只有你的API达到了Level 3水平以后,才能够谈论你的API是否是RESTful API。