2000年,Roy Thomas Fielding博士在他那篇著名的博士论文《Architectural Styles and the Design of Network-based Software Architectures》中提出了几种软件应用的架构风格,REST做为其中的一种架构风格在这篇论文的第5章中进行了归纳性的介绍。html
REST是“REpresentational State Transfer”的缩写,能够翻译成“表现状态转换”,可是在绝大多数场合中咱们只说REST或者RESTful。web
Fielding在论文中将REST定位为“分布式超媒体应用(Distributed Hypermedia System)”的架构风格,它在文中提到一个名为“HATEOAS(Hypermedia as the engine of application state)”的概念。api
SOAP Web API采用RPC风格,它采用面向功能的架构,因此咱们在设计SOAP Web API的时候首相考虑的是应高提供怎样的功能(或者操做)。安全
RESTful Web API采用面向资源的架构,因此在设计之初首先须要考虑的是有哪些资源可供操做。服务器
一个资源必须具备一个或者多个标识,既然咱们设计的Web API,那么很天然地应该采用URI来做为资源的标识。restful
除了必要的标志性和可选的可读性以外,标识资源的URI应该具备“可寻址性(Addressability)”。数据结构
URI不只仅指明了被标识资源所在的位置,并且经过这个URI能够直接获取目标资源。架构
在绝大多数状况下,资源并不会孤立地存在,必然与其它资源具备某种关联。app
利用URL将资源关联在一块儿,就是一份超文本/超媒体文档,咱们能够根据须要获取对应的资源,这也是爬虫的实现原理。负载均衡
Fielding在他的论文中将REST定位为“分布式超媒体应用”的架构风格,而超媒体的核心就是利用“连接”相关的信息结成一个非线性的网,因此从一点也能够看出REST和“使用连接关联相关的资源”这个特性使吻合的。
可否采用统一接口是RESTful Web API和采用RPC风格的SOAP Web服务又一区别。
#RPC风格
1: public class RoleService 2: { 3: public IEnumerable<string> GetAllRoles(); 4: public void CreateRole(string roleName); 5: public void DeleteRole(string roleName);
6: public void AddRolesInUser(string userName, string[] roleNames); 7: public void RemoveRolesFromUser(string userName, string[] roleNames); 8: }
#RESTful 1: public class RolesService 2: { 3: public IEnumerable<string> Get(); 4: public void Create(string roleName); 5: public void Delete(string roleName); 6: } 7: 8: public class RoleAssignmentsService 9: { 10: public void Create(RoleAssignment roleName); 11: public void Delete(RoleAssignment roleName); 12: }
Web API分别针对CRUD的操做只能接受具备对应HTTP方法的请求.
GET、HEAD和OPTIONS这三个HTTP方法旨在发送请求以或者所需的信息。
OPTIONS请求旨在发送一种“探测”请求以肯定针对某个目标地址的请求必须具备怎样的约束(好比应该采用怎样的HTTP方法以及自定义的请求报头),而后根据其约束发送真正的请求。
POST、PUT、PATCH和DELETE,它们旨在针对目标资源做添加、修改和删除操做。
经过发送POST和PUT请求都可以添加一个新的资源,可是二者的不一样之处在于:
对于前者,请求着通常不能肯定标识添加资源最终采用的URI,即服务端最终为成功添加的资源指定URI;
对于后者,最终标识添加资源的URI是能够由请求者控制的。
也正是由于这个缘由,若是发送PUT请求,咱们通常直接将标识添加资源的URI做为请求的URI;
对于POST请求来讲,其URI通常是标识添加资源存放容器的URI。
关于HTTP请求采用的这些个方法,具备两个基本的特性,即“安全性”和“幂等性”。
GET、HEAD和OPTIONS均被认为是安全的方法,由于它们旨在实现对数据的获取,并不具备“边界效应(Side Effect)”。
至于其它4个HTTP方法,因为它们会致使服务端资源的变化,因此被认为是不安全的方法。
幂等性(Idempotent)是一个数学上的概念,在这里表示发送一次和屡次请求引发的边界效应是一致的。
上述3种安全的HTTP方法(GET、HEAD和OPTIONS)均是幂等方法。
对于PUT请求,只有在对应资源不存在的状况下服务器才会进行添加操做,不然只做修改操做,因此它也是幂等方法。
至于最后一种POST,因为它老是进行添加操做,若是服务器接收到两次相同的POST操做,将致使两个相同的资源被建立,因此这是一个非幂等的方法。
当咱们在设计Web API的时候,应该尽可能根据请求HTTP方法的幂等型来决定处理的逻辑。
资源和资源的表示(Representaion)是两个不一样的概念,资源自己是一个抽象的概念,是看不见摸不着的,而看得见摸得着的是资源的表现。
对于Web来讲,目前具备两种主流的数据结构,XML和JSON,它们也是资源的两种主要的呈现方式。
咱们在设计Web API的时候,应该支持不一样的资源表示,咱们不能假定请求提供的资源必定表示成XML,也不能老是以JSON格式返回获取的资源,正确的作法是:根据请求携带的信息识别提交和但愿返回的资源表示。
对于请求提交的资源,咱们通常利用请求的Content-Type报头携带的媒体类型来判断其采用的表示类型。
对于响应资源表示类型的识别,能够采用以下两种方式:
1.让请求URI包含资源表示类型,这种方式使用的最多的是针对多语言的资源,咱们通常讲表示语言(也能够包含地区)的代码做为URI的一部分,好比“http://www.artech.com/en/orders/2013”表示将2013年的订单以英文的形式返回。
2.采用“内容协商(Content Negotiation)”根据请求相关报头来判断它所但愿的资源表示类型,好比“Accept”和“Accept-language”报头能够体现请求能够接受的响应媒体类型和语言。
RESTful只要维护资源的状态,而不须要维护客户端的状态。
对于它来讲,每次请求都是全新的,它只须要针对本次请求做相应的操做,不须要将本次请求的相关信息记录下来以便用于后续来自相同客户端请求的处理。
通常状况下,页面导航均具备“上一页”和“下一页”连接用于呈现当前页的前一页和后一页的记录。
那么如今有两种实现方式返回上下页的记录:
1.Web API不只仅会定义根据具体页码的数据查询定义相关的操做,还会针对“上一页”和“下一页”这样的请求定义单独的操做。
它自身会根据客户端的Session ID对每次数据返回的页面在本地进行保存,以便可以知道上一页和下一页具体是哪一页。
2.Web API只会定义根据具体页码的数据查询定义相关的操做,当前返回数据的页码由客户端来维护。
第一种貌似很“智能”,其实就是一种多此一举的做法,由于它破坏了Web API的无状态性。
设计无状态的Web API不只仅使Web API自身显得简单而精炼,还因减除了针对客户端的“亲和度(Affinty)”使咱们能够有效地实施负载均衡,由于只有这样集群中的每一台服务器对于每一个客户端才是等效的。