- [RESTful 架构详解](#restful-架构详解)
- [1. 什么是REST](#1-什么是rest)
- [2. RESTful的基本概念](#2-restful的基本概念)
- [3. 理解RESTful](#3-理解restful)
- [3.1 资源和URI](#31-资源和uri)
- [3.2 统一资源接口](#32-统一资源接口)
- [3.3 资源表述](#33-资源表述)
- [3.4 资源的链接](#34-资源的链接)
- [3.5 状态转移](#35-状态转移)
- [4. RESTful的最佳设计](#4-restful的最佳设计)
- [参考资料](#参考资料)
# RESTful 架构详解
## 1. 什么是REST
REST (Representational State Transfer),中文意思是:表述性状态转移。
一组架构约束条件和原则
如果一个架构符合 REST 的约束条件和原则,我们就称它为 RESTful 架构
## 2. RESTful的基本概念
1. 在 REST 中,一切的内容都被认为是一种资源
2. 每个资源都由 URI 唯一标识
3. 使用统一的接口处理资源请求(POST/GET/PUT/DELETE/HEAD)
4. 无状态(每次请求之前是无关联,没有 session )
## 3. 理解RESTful
要理解RESTful架构,需要理解Representational State Transfer这个词组到底是什么意思,它的每一个词都有些什么涵义。
下面我们结合REST原则,围绕资源展开讨论,从资源的定义、获取、表述、关联、状态变迁等角度,列举一些关键概念并加以解释。
- 资源与URI
- 统一资源接口
- 资源的表述
- 资源的链接
- 状态的转移
### 3.1 资源和URI
1. 使用 `/` 来表示资源的层级关系
2. 使用 `?` 用来过滤资源
3. 使用 `_` 或者 `-` 让URI的可读性更好
4. `,` 或 `;` 可以用来表示同级资源的关系
### 3.2 统一资源接口
| 请求方法 | 描述 |
| -------- | ------------------------------------------------------------ |
| GET | 获取某个资源。 幂等(取多少次结果都没有变化) |
| POST | 创建一个新的资源 |
| PUT | 替换某个已有的资源(更新操作) , 幂等(更新多次只保存一个结果) |
| DELETE | 删除某个资源 |
| HEAD | 主要用于确认 URL 的有效性以及资源更新的日期时间等 |
| PATCH | 新引入的,对PUT方法的补充,用来对已知资源进行局部更新 |
### 3.3 资源表述
上面提到,客户端通过 HTTP 方法可以获取资源,是吧? 不,确切的说,客户端获取的只是资源的表述而已。资源在外界的具体呈现,可以有多种表述(或成为表现、表示)形式,在客户端和服务端之间传送的也是资源的表述,而不是资源本身。 例如文本资源可以采用 html、xml、json 等格式,图片可以使用 PNG 或 JPG 展现出来。
资源的表述包括数据和描述数据的元数据,例如,HTTP 头 "Content-Type" 就是这样一个元数据属性。
那么客户端如何知道服务端提供哪种表述形式呢?
答案是可以通过 HTTP 内容协商,客户端可以通过 Accept 头请求一种特定格式的表述,服务端则通过 Content-Type 告诉客户端资源的表述形式。
MIME 类型
accept: text/xml html文件
Content-Type告诉客户端资源的表述形式
### 3.4 资源的链接
超媒体即应用状态引擎(可以做多层链接)
https://api.github.com/repos/github
```
{
"message": "Not Found",
"documentation_url": "https://developer.github.com/v3"
}
```
### 3.5 状态转移
服务器端不应该保存客户端状态。
应用状态 -> 服务器端不保存应用状态
访问订单 根据接口去查询
访问商品 查询
## 4. RESTful的最佳设计
以豆瓣网为例
1. 应该尽量将 API 部署在专用域名之下
`http://api.douban.com`/v2/user/1000001?apikey=XXX
2. 应该将 API 的版本号放入 URL
`http://api.douban.com/v2`/user/1000001?apikey=XXX
3. 在 RESTful 架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表格名对应。一般来说,数据库中的表都是同种记录的 ”集合”(collection),所以 API 中的名词也应该使用复数。
http://api.douban.com/v2/`book`/:id (获取图书信息)
http://api.douban.com/v2/`movie`/subject/:id (电影条目信息)
http://api.douban.com/v2/`music`/:id (获取音乐信息)
http://api.douban.com/v2/`event`/:id (获取同城活动)
4. 对于资源的具体操作类型,由 HTTP 动词表示。常用的 HTTP 动词有下面四个(对应 **增/删/改/查** )。
**GET**(select):从服务器取出资源(一项或多项)。
eg. 获取图书信息 【GET】
**POST**(create):在服务器新建一个资源。
eg. 用户收藏某本图书 【POST】
**PUT**(update):在服务器更新资源(客户端提供改变后的完整资源)。
eg. 用户修改对某本图书的收藏 【PUT】
**DELETE**(delete):从服务器删除资源。
eg. 用户删除某篇笔记 【DELETE】
5. 如果记录数量很多,服务器不可能都将它们返回给用户。API应该提供参数,过滤返回结果
`?limit=10`:指定返回记录的数量
eg. 获取图书信息 【GET】 `?limit=10`
6. 服务器向用户返回的状态码和提示信息
每个状态码代表不同意思, 就像代号一样
HTTP状态码
- 1系 信息
- 2系 正常返回
- 3系 重定向
- 4系 数据异常
- 5系 服务器异常
业务状态码
# 参考资料
- [RESTful 架构详解 | 菜鸟教程](https://www.runoob.com/w3cnote/restful-architecture.html)
- [RESTful API 设计指南 - 阮一峰的网络日志](http://www.ruanyifeng.com/blog/2014/05/restful_api.html)