RESTful APIs
设计规范
该文章是
RESTful Web APIs中文版
的重点概要。仅个人查阅使用,如要获取详细信息,可直接购买书籍。
RESTful
不是一种协议,也是一种文件格式,更不是一种开发框架。它是一系列的设计约束的集合:无状态性、将超媒体作为应用状态的引擎等。
1、资源 和 表述
- 资源 - 万物皆可为对象。
资源一般是可以保存到计算机里面的事物。比如电子文档,数据库的一条记录,或者是一条算法的运行结果等。
- 表述 - 表述用来描述资源状态。
当客户端对一个资源发起一个
GET
请求的时候,服务器会以一种有效的方式提供一个采集了资源信息的文档作为回应。这种回应被称为表述——以机器可读的方式对资源当前状态的说明。表述的类型有XML
文档、JSON
对象、用逗号分隔的数值等。
2、HTTP
请求类型
在
RESTful
系统里,客户端和服务端只能通过相互发遵循预定义协议得消息来进行交互。在web API领域中,这个协议就是HTTP
。
GET - 获取资源的某个表述。
GET
是被定义为安全的HTTP
方法。它仅仅是对信息的一次请求。向服务器发送一条GET
请求对资源的影响应该和没有发送GET
请求一样——也就是没有任何影响。像一些日志记录、速率限制等副作用是可以接受的,但是客户端绝对不要发起的GET
请求能改变资源的状态。
GET
请求中最常用的状态码是200(OK
);
如果客户端试图GET
一个不存在或已经被DELETE
的资源,服务器会返会错误状态码:404(Not Found
)或者410(Gone
)。
DELETE - 销毁一个资源。
当客户端希望一个资源消失的时候,它可以发送一个DELETE
请求。客户端这时候希望服务器将资源销毁,并且以后再也不会提到它。当然,服务器没有义务自我检查数据是否需要删除。
服务器返回状态是204(No Content
):表示资源已经被成功删除;
服务器返回状态是200(OK
):表示资源已经被成功删除,这里是关于它的一条消息;
服务器返回状态是202(Accepted
):我稍后将删除这个资源;
POST - 基于给定的表述,在当前资源的下一级创建新的资源。
-
POST-to-Append
向某个资源发送一条
POST
请求用于在该资源的下一级创建一个新的资源。当客户端发送一个POST-to-Append
请求的时候,它会在请求的实体消息体中添加所希望创建的资源的表述信息并发送给服务器。最常见的响应码是201(
Created
):告知资源已经成功创建;
另一种常见的响应码是202(Accepted
):表示服务器打算按照提供的表述信息来创建一个资源,但是现在还没有完成创建。 -
overloaded POST
在
web
开发时,对表单内容更新的时候,看似是PUT
请求,但是HTML
表单不能触发一个PUT
请求。HTML
数据格式并不允许这样做,所以我们使用POST
进行代替。
这是合法的。HTTP
规范中说POST
可以用于向数据处理流程提供例如表单提交结果的数据块。
POST方法既不安全,也不幂等。
PUT - 用给定的表述信息替换资源的当前状态。
PUT
请求是用于修改资源状态的请求。客户端一般会通过GET
请求获取表述,然后对其修改,最后将修改后的资源标为负载数据(payload
)通过PUT
请求发送回去。
客户端通常会收到200(OK
)或204(No Content
)状态码。
PUT
和DELETE
方法都是幂等的。你发送10次的请求和发送一次请求的结果是一致的。
PATCH - 根据提供的表述信息修改资源的部分状态。如果有些资源状态在提供的表述中没有提到,这些状态就保持不变。PATCH
类似与PUT
,但是允许对资源进行一些细粒度的改动。
PATCH
方法既不是安全的,也不是幂等的。 一个PATCH
请求有可能结果是幂等的,这种情况下,如果你一不小心对一个资源应用了两次PATCH
,你可能会在第二次收到一个错误信息。
3、幂等性
幂等的概念来自于数学。比如,幂等运算:5 X 0 是 0, 5 X 0 X 0还是 0。一旦你将一个数值乘以零,你就可以无限次的乘以零,你得到的都是同样一个结果:零。
在编程中幂等操作的特点是其任意多次运行产生的影响和一次运行产生的影响一致。
幂等性是指对资源产生的影响,而不是调用HTTP
返回的状态码。
HTTP DELETE
方法相当于用零乘以一个资源,它不是一个安全的方法(由于DELETE
是资源发送了变化),但它是一个幂等操作。
HTTP GET
方法相当于乘一操作,也是一个安全的方法。
HTTP PUT
方法是一个幂等方法。
每个安全的运算都是幂等的。
4、HTTP
状态码
HTTP
状态码是用以表示网页服务器超文本传输协议响应状态的3位数字代码。
1xx Informational
这一类型的状态码,代表请求已经被服务器接受,需要继续处理。这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束。
-
100 Continue
客户端应当继续发送请求。这个临时响应是通知客户端它的部分请求已经被服务器接收,且仍未拒绝。客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应。服务器必须在请求完成后向客户端发送一个最终响应。
-
101 Switching Protocols
-
102 Processing
-
103 Checkpoint
2xx Success
这一类状态码,表示请求已经被服务器成功的接受、理解并处理。
- 200 OK
请求成功。请求所希望的响应头或数据体将随此响应返回。
- 201 Created
请求已经被实现,而且有一个新的资源已经依据请求的需要而建立,且其URI已经随Location
头信息返回。假如需要的资源没有及时建立的话,应当返回202(Accepted
)。
- 202 Accepted
服务器已经接收请求,但尚未处理。它也有可能被拒绝,最后该请求可能不会被执行。在异步操作场景下,没有比返回202更简单的做法了。
返回202状态码的响应目的是允许服务器接受其它请求的过程(例如某个每天只执行一次的基于批处理的操作),而不是让客户端一直保持与服务器的连接直到服务器运行结束。在接受请求处理并返回202状态码的响应应当在返回的实体中包含一些指示处理当前状态的信息,以及指向处理状态监视器或状态预测的指针,以便用户能够估计操作是否已经完成。
- 203 Non-Authoritative Information
- 204 No Content
- 205 Reset Content
- 206 Partial Content
- 207 Multi-Status
- 208 Already Reported
- 226 IM Used
3xx Redirection
这类状态码代表需要客户端采取进一步的操作才能完成请求。通常,这些状态码用来重定向,后续的请求地址(重定向目标)在本次响应的 Location 域中指明。
-
300 Multiple Choices
-
301 Moved Prmanently
被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个 URI 之一。如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。除非额外指定,否则这个响应也是可缓存的。
新的永久性的URI 应当在响应的 Location 域中返回。除非这是一个 HEAD 请求,否则响应的实体中应当包含指向新的 URI 的超链接及简短说明。
如果这不是一个 GET 或者 HEAD 请求,因此浏览器禁止自动进行重定向,除非得到用户的确认,因为请求的条件可能因此发生变化。
注意:对于某些使用 HTTP/1.0 协议的浏览器,当它们发送的 POST 请求得到了一个301响应的话,接下来的重定向请求将会变成 GET 方式。 -
302 Found
-
303 See Other
-
304 Not Modified
-
307 Temporary Redirect
-
308 Permanent Redirect
4xx Client Error
这类的状态码代表了客户端看起来可能发生了错误,妨碍了服务器的处理。除非响应的是一个 HEAD 请求,否则服务器就应该返回一个解释当前错误状况的实体,以及这是临时的还是永久性的状况。这些状态码适用于任何请求方法。浏览器应当向用户显示任何包含在此类错误响应中的实体内容。
-
400 Bad Request
语义有误,当前请求无法被服务器理解。除非进行修改,否则客户端不应该重复提交这个请求。
请求参数有误。 -
401 Unauthorized
当前请求需要用户验证。该响应必须包含一个适用于被请求资源的 WWW-Authenticate 信息头用以询问用户信息。客户端可以重复提交一个包含恰当的 Authorization 头信息的请求。如果当前请求已经包含了 Authorization 证书,那么401响应代表着服务器验证已经拒绝了那些证书。如果401响应包含了与前一个响应相同的身份验证询问,且浏览器已经至少尝试了一次验证,那么浏览器应当向用户展示响应中包含的实体信息,因为这个实体信息中可能包含了相关诊断信息。
-
402 Payment Required
-
403 Forbidden
服务器已经理解请求,但是拒绝执行它。与401响应不同的是,身份验证并不能提供任何帮助,而且这个请求也不应该被重复提交。如果这不是一个 HEAD 请求,而且服务器希望能够讲清楚为何请求不能被执行,那么就应该在实体内描述拒绝的原因。当然服务器也可以返回一个404响应,假如它不希望让客户端获得任何信息。
-
404 Not Found
请求失败,请求所希望得到的资源未被在服务器上发现。没有信息能够告诉用户这个状况到底是暂时的还是永久的。假如服务器知道情况的话,应当使用410状态码来告知旧资源因为某些内部的配置机制问题,已经永久的不可用,而且没有任何可以跳转的地址。404这个状态码被广泛应用于当服务器不想揭示到底为何请求被拒绝或者没有其他适合的响应可用的情况下。出现这个错误的最有可能的原因是服务器端没有这个页面。
-
405 Method Not Allowed
-
406 Not Acceptable
-
407 Proxy Authentication Required
-
408 Request Timeout
-
409 Comflict
-
410 Gone
-
411 Length Required
-
412 Percondition Failed
-
413 Payload Too Large
-
414 URI Too Long
-
415 Unsupport Media Type
-
416 Requested rang not satisfiable
-
417 Expectation Failed
-
418 I’m a teapot
-
422 Unprocessable Entity
-
423 Locked
-
424 Failed Dependency
-
426 Upgrade Required
-
428 Precondition Required
-
429 Too Many Requests
-
431 Request Header Fields Too Large
-
451 Unavailable For Legal Reasons
5xx Server Error
这类状态码代表了服务器在处理请求的过程中有错误或者异常状态发生,也有可能是服务器意识到以当前的软硬件资源无法完成对请求的处理。除非这是一个HEAD 请求,否则服务器应当包含一个解释当前错误状态以及这个状况是临时的还是永久的解释信息实体。浏览器应当向用户展示任何在当前响应中被包含的实体。
-
500 Internal Server Error
服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器端的源代码出现错误时出现。
-
501 Not Implemented
-
502 Bad Gateway
作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。
-
503 Service Unavailable
-
504 Gateway Timeout
-
505 HTTP Version not supported
-
506 Variant Also Negotiates
-
507 Insufficient Storage
-
508 Loop Detected
-
509 Bandwidth Limit Exceeded
-
511 Network Authentication Required