restful 风格介绍


Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

下面是restful的设计要求

域名

应该尽量将API部署在专用域名之下。

https://api.example.com

如果确定API很简单,不会有进一步扩展,可以考虑放在主域名下。

https://example.org/api/

版本

应该将API的版本号放入URL。这样就可以方便不同版本的API共存且不打扰

https://api.example.com/v1/

路径URL

在RESTful架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表格名对应。一般来说,数据库中的表都是同种记录的”集合”(collection),所以API中的名词也应该使用复数。

如果要获取复数资源中的某一个资源,需要把资源id放入路径中,比如我获取某一个文章:posts/{id},这个id就是文章id了

还有就是要注意url里面不要出现大写字母统一用小写字母

避免多级url

url里面尽量只放一个参数,其他参数放在请求体中,除了第一级,其他级别都用查询字符串表达。

GET /authors/12?categories=2

动词

RESTful 的核心思想就是,客户端发出的数据操作指令都是”动词 + 宾语”的结构。比如,GET /articles这个命令,GET是动词,/articles是宾语。

常用的五种动词

GET:读取(Read)
POST:新建(Create)
PUT:更新(Update)
PATCH:更新(Update),通常是部分更新
DELETE:删除(Delete)

参数过滤

如果记录数量很多,服务器不可能都将它们返回给用户。API应该提供参数,过滤返回结果。

下面是一些常见的参数。

  • ?limit=10:指定返回记录的数量
  • ?offset=10:指定返回记录的开始位置。
  • ?page=2&per_page=100:指定第几页,以及每页的记录数。
  • ?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。
  • ?animal_type_id=1:指定筛选条件

参数的设计允许存在冗余,即允许API路径和URL参数偶尔有重复。比如,GET /zoo/ID/animals 与 GET /animals?zoo_id=ID 的含义是相同的。

状态码

服务器向用户返回的状态码和提示信息,常见的有以下一些(方括号中是该状态码对应的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 - [*]:服务器发生错误,用户将无法判断发出的请求是否成功

2xx状态码表示操作成功,不同的方法可以返回更精确的状态码。

API 用不到301状态码(永久重定向)和302状态码(暂时重定向,307也是这个含义),因为它们可以由应用级别返回,浏览器会直接跳转,API 级别可以不考虑这两种情况。

4xx状态码表示客户端错误,主要有下面几种。

5xx状态码表示服务端错误。一般来说,API 不会向用户透露服务器的详细信息,所以只要两个状态码就够了。

返回的数据

不要返回纯文本数据,应该返回一个json对象,服务器回应的 HTTP 头的Content-Type属性要设为application/json

不推荐把code放在请求体里,应该直接返回数据,比如不推荐下面这种

需要改成

如果发生错误,不要返回200状态码,而是直接返回对应的错误码

不同请求返回结果

不同操作服务器应该返回不同的结果

GET /collection:返回资源对象的列表(数组)
GET /collection/resource:返回单个资源对象
POST /collection:返回新生成的资源对象
PUT /collection/resource:返回完整的资源对象
PATCH /collection/resource:返回完整的资源对象
DELETE /collection/resource:返回一个空文档

restful如何实现批量删除

有两种方式

1.用逗号分隔放进url里面:http://example.com/posts/2016,2017

2.第一步发送POST请求,集合所有要删除的IDs然后返回一个header,然后在利用这个header调用DELETE请求。具体步骤如下:
发送POST请求,集中所有的IDs (可以存到Redis或者普通数据库)
http://example.com/posts/deletes

成功后可以返回一个唯一的头文件:

HTTP/1.1 201 created, and a Location header to:
http://example.com/posts/deletes/KJHJS675

然后可以利用Ajax直接发送DELETE请求:
DELETE http://example.com/posts/deletes/KJHJS675

这样就可以在不暴露IDs的情况下更加安全的删除相关条目。

验证

不要用cookie来进行验证,必须要使用token来验证,同时token要放head中,不要放请求体里

参考:

1.RESTful API 最佳实践 - 阮一峰的网络日志 (ruanyifeng.com)

2.RESTful API 设计指南 - 阮一峰的网络日志 (ruanyifeng.com)


文章作者: 小游
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 小游 !
  目录