1. 什么是REST
REST全称是Representational State Transfer,中文意思是表述(编者注:一般译为表征)性状态转移。 它首次出如今2000年Roy Fielding的博士论文中,Roy Fielding是HTTP规范的主要编写者之一。 他在论文中提到:"我这篇文章的写做目的,就是想在符合架构原理的前提下,理解和评估以网络为基础的应用软件的架构设计,获得一个功能强、性能好、适宜通讯的架构。REST指的是一组架构约束条件和原则。" 若是一个架构符合REST的约束条件和原则,咱们就称它为RESTful架构。html
REST自己并无创造新的技术、组件或服务,而隐藏在RESTful背后的理念就是使用Web的现有特征和能力, 更好地使用现有Web标准中的一些准则和约束。虽然REST自己受Web技术的影响很深, 可是理论上REST架构风格并非绑定在HTTP上,只不过目前HTTP是惟一与REST相关的实例。 因此咱们这里描述的REST也是经过HTTP实现的REST。web
什么是RESTful架构:json
每个URI表明一种资源;
客户端和服务器之间,传递这种资源的某种表现层;
客户端经过四个HTTP动词(GET/POST/PUT/DELETE),对服务器端资源进行操做,实现”表现层状态转化”。
segmentfault
URI
要让一个资源能够被识别,须要有个惟一标识,在Web中这个惟一标识就是URI(Uniform Resource Identifier)。 URI既能够当作是资源的地址,也能够当作是资源的名称。若是某些信息没有使用URI来表示,那它就不能算是一个资源, 只能算是资源的一些信息而已。URI的设计应该遵循可寻址性原则,具备自描述性,须要在形式上给人以直觉上的关联。api
HTTP动词
数组
1. 使用GET、POST、PUT、DELETE这几种请求模式
请求模式也能够说是动做、数据传输方式,一般咱们在web中的form有GET、POST两种,而在HTTP中,存在下发这几种。服务器
GET (选择):从服务器上获取一个具体的资源或者一个资源列表。
POST (建立): 在服务器上建立一个新的资源。
PUT(更新):以总体的方式更新服务器上的一个资源。
PATCH (更新):只更新服务器上一个资源的一个属性。
DELETE(删除):删除服务器上的一个资源。restful
1.1 使用名词而不是动词
Resource
资源网络
GET
读 POST
建立 PUT
修改 DELETE
/cars 返回 cars集合 建立新的资源 批量更新cars 删除全部cars
/cars/711 返回特定的car 该方法不容许(405) 更新一个指定的资源 擅长指定资源
不要使用:数据结构
/getAllCars
/createNewCar
/deleteAllRedCars
1.2 Get方法和查询参数不该该涉及状态改变
使用PUT, POST 和DELETE 方法 而不是 GET 方法来改变状态,不要使用GET 进行状态改变:
GET /users/711?activate
GET /users/711/activate
1.3 使用复数名词
不要混淆名词单数和复数,为了保持简单,只对全部资源使用复数。
/cars 而不是 /car
/users 而不是 /user
/products 而不是 /product
/settings 而部署 /setting
1.4 使用子资源表达关系
若是一个资源与另一个资源有关系,使用子资源:
GET /cars/711/drivers/ 返回 car 711的全部司机
GET /cars/711/drivers/4 返回 car 711的4号司机
2. 为集合提供过滤 排序 选择和分页等功能
好比在数据过多, 须要对数据进行分页请求的时候, 咱们应该统一 API 请求参数. 常见的有这些.
limit=10 指定返回记录的数量
offset=10 指定返回记录的开始位置。
page=2&per_page=100 指定第几页,以及每页的记录数。
sortby=name&order=asc 指定返回结果按照哪一个属性排序,以及排序顺序。
animal_type_id=1 指定筛选条件
Filtering过滤:
使用惟一的查询参数进行过滤:
GET /cars?color=red 返回红色的cars
GET /cars?seats<=2 返回小于两座位的cars集合
Sorting排序:
容许针对多个字段排序
GET /cars?sort=-manufactorer,+model
这是返回根据生产者降序和模型升序排列的car集合
Field selection
移动端可以显示其中一些字段,它们其实不须要一个资源的全部字段,给API消费者一个选择字段的能力,这会下降网络流量,提升API可用性。
GET /cars?fields=manufacturer,model,id,color
Paging分页
使用 limit 和offset.实现分页,缺省limit=20 和offset=0;
GET /cars?offset=10&limit=5
为了将总数发给客户端,使用订制的HTTP头: X-Total-Count.
连接到下一页或上一页能够在HTTP头的link规定,遵循Link规定:
Link: <https://blog.mwaysolutions.com/sample/api/v1/cars?offset=15&limit=5>; rel="next",
<https://blog.mwaysolutions.com/sample/api/v1/cars?offset=50&limit=3>; rel="last",
<https://blog.mwaysolutions.com/sample/api/v1/cars?offset=0&limit=5>; rel="first",
<https://blog.mwaysolutions.com/sample/api/v1/cars?offset=5&limit=5>; rel="prev",
3. 版本化你的API
API的开发直接关系了APP是否能够正常使用,若是本来运行正常的API,忽然改动,那么以前使用这个API的APP可能没法正常运行。APP是不可能强迫用户主动升级的,所以,经过API版原本解决这个问题。也就是说,API的多个版本是同时运行的,并且都要保证能够正常使用。
按照RESTful的规范,不一样的版本也应该用相同的API URL,经过header信息来判断版本,再调用不一样版本的程序进行处理。可是这明显会给开发带来巨大的成本。使得API版本变得强制性,不要发布无版本的API,使用简单数字,避免小数点如2.5.
域名
应该尽可能将API部署在专用域名之下,如:https://api.example.com
也能够放在主域名下:https://example.org/api/
版本
不一样的版本,用不一样的URL来提供服务,在URL中经过v一、v2来区分版本号,好比v2.api.xxx.com/user的方式,或者http://api.domain.com/v2 或者http://www.domain.com/api/v2 。
放入到头信息的Accept中
制定版本并在版本之间平缓过渡对于设计和维护一套API是个巨大的挑战。因此,最好在设计之初就使用一些方法来预防可能会遇到的问题。
为了不API的变更致使用户使用中产生意外结果或调用失败,最好强制要求全部访问都须要指定版本号。请避免提供默认版本号,一旦提供,往后想要修改它会至关困难。
最适合放置版本号的位置URL中,或者是头信息(HTTP Headers)中在 Accept 段中使用自定义类型(content type)与其余元数据(metadata)一块儿提交。
https://api.example.com/v1/
或
Accept: application/vnd.heroku+json; version=3
提供 Request-Id
为每个请求响应包含一个Request-Id字段,并使用UUID做为该值。经过在客户端、服务器或任何支持服务上记录该值,它能主咱们提供一种机制来跟踪、诊断和调试请求。
4 .json数据类型
Number:整数或浮点数
String:字符串
Boolean:true 或 false
Array:数组包含在方括号[]中
Object:对象包含在大括号{}中
Null:空类型
因此,传输的数据类型不能超过这六种数据类型。之前,咱们曾经试过传输Date类型,它会转为相似于"2016年1月7日 09时17分42秒 GMT+08:00"这样的字符串,这在转换时会产生问题,不一样的解析库解析方式可能不一样,有的可能会转乱,有的可能直接异常了。要避免出错,必须作特殊处理,本身手动去作解析。为了根除这种问题,最好的解决方案是用毫秒数或者字符串表示日期。
使用详细的错误包装错误:
{
"errors": [
{
"userMessage": "Sorry, the requested resource does not exist",
"internalMessage": "No car found in the database",
"code": 34,
"more info": "http://dev.mwaysolutions.com/blog/api/v1/errors/12345"
}
]
}
返回的数据结构
{
code:0,
message: "success",
data: { key1: value1, key2: value2, ... }
}
code: 返回码,0表示成功,非0表示各类不一样的错误
message: 描述信息,成功时为"success",错误时则是错误信息
data: 成功时返回的数据,类型为对象或数组
data字段只在请求成功时才会有数据返回的。数据类型限定为对象或数组,当请求须要的数据为单个对象时则传回对象,当请求须要的数据是列表时,则为某个对象的数组。这里须要注意的就是,不要将data传入字符串或数字,即便请求须要的数据只有一个,好比token,那返回的data应该为:
// 正确 data: { token: abcdedf }
9. 使用Http状态码处理错误
不一样错误须要定义不一样的返回码,属于客户端的错误和服务端的错误也要区分,好比1XX表示客户端的错误,2XX表示服务端的错误
若是你的API没有错误处理是很难的,只是返回500和出错堆栈不必定有用
Http状态码提供70个出错,咱们只要使用10个左右:
200 OK - [GET]:服务器成功返回用户请求的数据,该操做是幂等的(Idempotent)。
201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
204 NO CONTENT - [DELETE]:用户删除数据成功。
400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操做,该操做是幂等的。
401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
403 Forbidden - [*] 表示用户获得受权(与401错误相对),可是访问是被禁止的。
404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操做,该操做是幂等的。
406 Not Acceptable - [GET]:用户请求的格式不可得(好比用户请求JSON格式,可是只有XML格式)。
410 Gone -[GET]:用户请求的资源被永久删除,且不会再获得的。
422 Unprocesable entity - [POST/PUT/PATCH] 当建立一个对象时,发生一个验证错误。
500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将没法判断发出的请求是否成功。
10.容许覆盖http方法
一些代理只支持POST 和 GET方法, 为了使用这些有限方法支持RESTful API,须要一种办法覆盖http原来的方法。
使用订制的HTTP头 X-HTTP-Method-Override 来覆盖POST 方法.
参考:
https://segmentfault.com/a/1190000008697972#articleHeader3http://blog.csdn.net/jasonhui512/article/details/53141390http://www.cnblogs.com/kuyuecs/p/5949075.htmlhttp://mclspace.com/2015/11/03/restful-note/--------------------- 做者:曾先森向前进 来源:CSDN 原文:https://blog.csdn.net/zwqjoy/article/details/78788915 版权声明:本文为博主原创文章,转载请附上博文连接!