【原创文章,转载请注明原文章地址,谢谢!】
摘要,本文主要是简单讨论RESTful的相关设计问题,包括资源设计,动作设计和响应设计。
资源设计
在本系列第一篇文章中已经通过一个优惠券的例子给大家简单阐述了一下资源的设计,包括二级资源的设计。下面我们来看下详细的资源设计方案:
前面我们已经了解到,在RESTful架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表格名对应。一般来说,数据库中的表都是同种记录的”集合”(collection),所以API中的名词也应该使用复数。
例如,针对一个动物园应用,可能涉及到的资源就应该有:
https://api.example.com/v1/zoos:动物园资源
https://api.example.com/v1/animals:动物资源
https://api.example.com/v1/employees:饲养员资源
注意设计的方案,最后一个单词都是名词并且都是复数。对于简单的应用来说,一般一个资源就对应一个表,这样的设计已经足够。但是更多的情况,面对复杂的应用,因为HTTP提供的接口是有限的(HTTP一共就提供了常用的5种请求方式,所以能表示的对一个资源的操作是有限的)怎么抽取出合适的资源,也是一个相对来说比较困难的事情。这个在我们后面的实战示例中会提到。
动作设计
先来看看REST中针对HTTP常用动作的一些固定的含义:
- GET(SELECT):表示从服务器取出资源(一项或多项)。
- POST(CREATE):表示在服务器新建一个资源。
- PUT(UPDATE):表示在服务器更新资源(客户端需要提供改变后的完整资源)。
- PATCH(UPDATE):表示在服务器更新资源(客户端需要提供改变的属性【可以简单理解为补丁】)。
- DELETE(DELETE):表示从服务器删除资源。
以上五个是最常用的请求方式;另外还有两个:
- HEAD:获得一个资源的元数据,比如一个资源的hash值或者最后修改日期;
- OPTIONS:获得客户针对一个资源能够实施的操作;这个主要是作为Hypermedia 存在(在最佳实践中介绍)
下面列几个简单的动作示例,示例格式 HTTP动作 URL:说明
- GET /zoos:列出所有动物园
- POST /zoos:新建一个动物园
- GET /zoos/ID:获取某个指定动物园的信息(ID即指定动物园id)
- PUT /zoos/ID:更新某个指定动物园的信息(浏览器端需要提供该动物园的全部信息)
- PATCH /zoos/ID:更新某个指定动物园的信息(浏览器端需要提供该动物园的部分信息)
- DELETE /zoos/ID:删除某个动物园
- GET /zoos/ID/animals:列出某个指定动物园的所有动物(animals为二级资源路径)
- DELETE /zoos/ID/animals/ID:删除某个指定动物园的指定动物animals为二级资源路径,前面一个id是指定动物园id,后面一个id是指定动物id)
返回结果
返回结果也是HTTP协议中非常重要的组成部分,客户端完全通过返回结果来断定请求的结果,包括异常等。
返回值类型
即针对不同的请求方式,应该返回什么标准的内容。但是注意,具体返回什么样式的内容,是通过头信息来规定的。下面直接使用一些案例来说明:
- GET /collection:规定返回资源对象的列表(数组)
- GET /collection/resource:规定返回单个资源对象
- POST /collection:规定返回新生成的资源对象
- PUT /collection/resource:规定返回完整的资源对象
- PATCH /collection/resource:规定返回完整的资源对象
- DELETE /collection/resource:规定返回一个空文档
Content Type
一个API可以允许返回JSON,XML甚至HTML等文档格式;具体的文档格式由头信息规定。而头信息来源于两点,一个是请求头中的Accept Type,表示客户端需要请求的表现层数据格式。一个是响应头中的Content Type,表示本次请求服务器端返回的数据格式。
另外,完全也可以通过URI后缀来表示请求格式,比如GET /animals.json用来表示请求json格式的动物列表数据,使用GET /animals.xml来表示请求XML格式的动物列表数据,但是更建议使用请求头来表示,不要把数据类型和资源混淆。
返回状态码
返回状态码在HTTP/1.1协议中是一个非常重要的概念。表示了本次请求的一个最终的效果,也是客户端判定本次请求结果的第一个入口。返回状态码非常多,下面简单列举了常用的返回状态码说明(格式:状态码 状态码说明 适合的请求类型:解释):
- 200 OK – [GET]:服务器成功返回用户请求的数据。
- 201 CREATED – [POST/PUT/PATCH]:用户新建或修改数据成功(但是大部分情况下,使用200也是可以的)。
- 202 Accepted – [*]:表示一个请求已经进入后台排队(针对异步请求,或者后台服务需要一定处理时间的请求)
- 204 NO CONTENT – [DELETE]:用户删除数据成功(但是大部分情况下,使用200也是可以的)。
- 400 INVALID REQUEST – [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等(幂等的意思是针对一个数据,多次实施相同的操作效果是一致的。比如多次删除一条数据,最后的效果是一样的,即这条数据被删除,那么删除操作是幂等的,而对于++运算符,每次操作的结果都是在上一次数据值上面加1,所以++操作不是幂等的)的。
- 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 – [*]:服务器发生错误,用户将无法判断发出的请求是否成功。
小结
在本节中,主要针对RESTful的常见的设计做出了一些解释,到此,关于RESTful的基本概念介绍完毕,要真正的去理解和体会RESTful的好处,还需要在实际的开发中慢慢看。从下一篇文章开始,进入RESTful的开发基础介绍。