Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
下面是restful的设计要求
域名
应该尽量将API部署在专用域名之下。
如果确定API很简单,不会有进一步扩展,可以考虑放在主域名下。
版本
应该将API的版本号放入URL。这样就可以方便不同版本的API共存且不打扰
路径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中,不要放请求体里