
一句话概括 RESTful API(具有 REST 风格的 API): 用 URL 定位资源,用 HTTP 动词(GET,HEAD,POST,PUT,PATCH,DELETE)描述操作,用响应状态码表示操作结果
再接着详细说明下 REST
REST 是什么
REST(representational state transfer)——表象性状态转移或表述性状态转移
- Rest 是 web 服务的一种架构风格,使用 HTTP,URI,JSON,HTML 等广泛流行的标准和协议
- 轻量级,跨平台,跨语言的架构设计
- restful 是一种设计风格,不是一种标准,是一种思想
REST 架构主要原则(简化版本):
- 网络上的所有事物都被抽象为资源
- 每个资源都有唯一的资源标识符(URI)
- 同一个资源具有多种表现形式(xml,json)
- 对资源的各种操作不会改变资源标识符(重点)
- 所有的操作都是无状态的
(原义六个限制,参考 怎样用通俗的语言解释REST,以及RESTful?)
符合 REST 原则的结构方式即可成为 RESTful——rest 式的
常见:Restful web service(ROA, 面向资源的架构)
为什么会有 REST?
先看一段 REST 提出者(Roy T. Fielding)的话
Throughout the HTTP standardization process, I was called on to defend the design choices of the Web. That is an extremely difficult thing to do within a process that accepts proposals from anyone on a topic that was rapidly becoming the center of an entire industry. I had comments from well over 500 developers, many of whom were distinguished engineers with decades of experience, and I had to explain everything from the most abstract notions of Web interaction to the finest details of HTTP syntax. That process honed my model down to a core set of principles, properties, and constraints that are now called REST.
在整个 HTTP 标准化过程中,我被要求捍卫网络的设计选择。这是一个非常困难的事情,即在一个接受来自任何人的主题的提案,这是一个迅速成为整个行业中心的主题。我从超过 500 个开发人员中发表评论,其中许多人都有几十年的经验,我不得不从 Web 交互的最抽象概念到 HTTP 语法的最佳细节中解释一切。该过程将我的模型磨练到现在称为 REST 的核心原则,属性和约束。
在 Restful 之前的操作:
- http://127.0.0.1/user/query/1 GET 根据用户 id 查询用户数据
- http://127.0.0.1/user/save POST 新增用户
- http://127.0.0.1/user/update POST 修改用户信息
- http://127.0.0.1/user/delete/1 GET/POST 删除用户信息
RESTful 用法:
- http://127.0.0.1/user/1 GET 根据用户 id 查询用户数据
- http://127.0.0.1/user POST 新增用户
- http://127.0.0.1/user PUT 修改用户信息
- http://127.0.0.1/user DELETE 删除用户信息
之前的操作是没有问题的,大神认为是有问题的,有什么问题呢?每次请求的接口或者地址,都在做描述
例如查询的时候用了query,新增的时候用了save,其实完全没有这个必要,我使用了get请求,就是查询.使用post请求,就是新增的请求,我的意图很明显,完全没有必要做描述,这就是为什么有了restful.REST 三大结构
用 URL 定位资源
在 RESTful 架构风格中,URL 用来指定一个资源
资源就是服务器上可操作的实体(可以理解为数据)
比如说 URL/api/users 表示的是该网站的所有用户,这是一种资源,可以与之互动(获取、提交、更新、删除)
另外,资源地址具有层次结构,比如/api/users/csr 表示用户名为 'csr' 的用户,/api/users/csr/blogs 表示 'csr' 的所有博客,/api/users/csr/blogs/1234567 表示其中的某一篇博客。这些都是资源,后者嵌套在前者之中。
既然 URL 表示一个资源,自然就不应该包含动词,它应该由名词组成。一个 not RESTful 的例子是通过向 api/delete/resource 发送 GET 请求来删除一个资源。
更详细的 URL 设计可以查看阮一峰的 "RESTful API 设计指南 " 或者知乎高票回答。URL 风格只是 REST 的外表,不是本文的重点。
操作资源
既然通过 URL 能够指定一个服务器上的资源。那么我们应该如何与这个资源进行互动呢?我们对这个资源 (URL) 使用不同的 HTTP 方法,就代表对这个资源的不同操作:
- GET(SELECT):从服务器获取资源(一个资源或资源集合)
- POST(CREATE):在服务器新建一个资源(也可以用于更新资源)
- PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源,
对比post的更新) - PATCH(UPDATE):在服务器更新资源(客户端提供改变的部分)
- DELETE(DELETE):从服务器删除资源
- HEAD:获取资源的元数据
- OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的
GET、HEAD、PUT、DELETE 方法是 幂等方法 (对于同一个内容的请求,发出 n 次的效果与发出 1 次的效果相同)。
GET、HEAD 方法是 安全方法 (不会造成服务器上资源的改变)
PATCH 不一定是幂等的。PATCH 的实现方式有可能是 " 提供一个用来替换的数据 ",也有可能是 " 提供一个更新数据的方法 "(比如 data++)。如果是后者,那么 PATCH 不是幂等的。

参考:HTTP Methods for RESTful Services
通过 HTTP 状态码表示操作的结果
虽然 HTTP 状态码设计的本意就是表示操作结果,但是有时候人们往往没有很好的利用它,RESTful API 要求充分利用 HTTP 状态码
- 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 - [* ]:服务器发生错误,用户将无法判断发出的请求是否成功。
总结
至此,我们应该能够体会到 REST 已经不仅仅是一种 API 风格了,它是一种软件架构风格 (REST 本身不是一种架构)。REST 风格的软件架构具有很强的演化、拓展能力:
- 一致的 URL 和 HTTP 动词使用:确保系统能够接纳多样而又标准的客户端,保证客户端的演化能力
- 无状态:保证了系统的横向拓展能力、服务端的演化能力
- HATEOAS:保证了应用本身的演化能力 (功能增加、改变)