一、前言
在刚接触开发的时候,就在网上看到有人说接口的设计只用get和post请求,一直不明白为什么要这样做,最近在使用 AI 进行开发的时候,AI又会频繁使用 RESTful 风格去定义接口。今天在这里写一篇文章记录一下,如果存在错误,还望指出。
二、RESTful风格的接口设计
RESTful风格接口设计是 一种基于HTTP协议语义、资源导向、无状态、可缓存的Web API 设计方法。要注意的是, RESTful 不是一种规范,只是一种风格,它不具有强制性,因此有许多的开发者并不按照它规定的方式进行开发,也就导致了最开始的问题——很多接口设计只用GET和POST请求。
在RESTful中GET、POST、PUT、DELETE四中HTTP请求方法。具体如下:
| HTTP方法 | 语义 | 幂等性 | 安全性 | 用途 |
|---|---|---|---|---|
| GET | 获取资源 | √ | × | 查询章节列表 |
| POST | 创建资源 | × | × | 新建章节 |
| PUT | 全量更新 | √ | × | 替换整个章节的信息 |
| DELETE | 删除资源 | √ | × | 删除章节 |
1 GET请求
GET请求用于从服务器检索资源,通常用于获取数据。
- GET请求是幂等的,即多次执行相同的GET请求,服务器返回的结果是一致的。
- GET请求是安全的,不会对服务器资源状态产生任何副作用。
- GET请求的参数通常通过URL查询字符串传递,而不是请求体,并且可以被缓存以提高性能。
在使用的时候不应该在GET请求中传递敏感信息,并且URL的长度有限制,通常建议小于2048个字符。
1.1 响应码
- 200(OK) - 表示已在响应中发出
- 204(无内容) - 资源有空表示
- 301(moved permanently) - 资源的URL已被更新
- 303(see other) - 其他,如负载均衡
- 304(not modified) - 资源未更改(缓存)
- 400(bad equest) - 代指坏请求,如参数错误
- 404(not found) - 资源不存在
- 406(not acceptable) - 服务端不支持所需表示
- 500(internal server error) - 通用错误表示
- 503(service unavailable) - 服务端当前无法处理请求
2 POST请求
POST请求用于向服务器提交数据以创建新资源,例如提交表单或上传文件。
- POST 请求通常不是幂等的。每次执行相同的 POST 请求可能会创建一个新的资源,导致不同的结果。
- POST 请求不是安全的,因为他会对服务器产生副作用,例如在数据库中插入新记录,重复请求就可能导致插入了多条相同的数据。
- POST 请求的数据通常包含在请求体中,适合传输大量或结构化数据,没有URL长度限制。
- POST 请求不能被缓存。
2.1 响应码
- 200(OK) - 如果现有资源已被更改
- 201(created) - 如果新资源被创建
- 202(accepted) - 已接受处理请求但尚未完成(异步处理)
- 301(moved permanently) - 资源的 URI 被更新
- 303(see other) - 其他,如负载均衡
- 400(bad request) - 指代坏请求
- 404(not found) - 资源不存在
- 406(not acceptable) - 服务端不支持所需表示
- 409(conflict) - 通用冲突
- 412(precondition failed) - 前置条件失败,如执行条件更新时的冲突
- 415(unsupported media type) - 接受到的表示不受支持
- 500(internal server error) - 通用错误响应
- 503(Service Unavailable) - 服务当前无法处理请求
3 PUT请求
PUT 请求用于全量更新服务器上的资源。它会用请求体中的数据完全替换目标资源的当前内容。
- PUT 请求是幂等的。无论执行多少次,只要传递的数据相同,资源的最终状态也是一致的。
- PUT 请求是不安全的,因为它会修改资源的状态。
- PUT 请求的数据通常包含在请求体中。
- PUT 请求使用替换的方式更新资源的,因此需要知道指定资源的ID。
3.1 响应码
同2.1节
4 DELETE请求
DELETE 请求用于删除服务器上的资源。
- DELETE 请求是幂等的。无论执行多少次,资源的状态(即被删除)都保持不变。
- DELETE 请求是不安全的,因为它会对服务器产生副作用,如从数据库中删除数据。
- DELETE 请求通常不包含请求体。
三、为什么不使用 PUT 和 DELETE 请求
在了解了 RESTful 风格的四种 HTTP 接口设计之后,再结合实际开发中遇到的一些场景,大家心里应该都有了一些答案。
假如说我现在要查询和修改章节的话,那么使用 RESTful 风格的接口命名就会变成这个样子
GET /novel/{novelId}/chapter/{id}
PUT /novel/{novelId}/chapter/{id}
如果不去看请求方式,它们的路径和响应体完全是一样的,当遇到一些其他的场景时,比如现在我需要发布章节,更新章节名称,接口又会变成下面这样,注:PATCH请求和PUT请求类似,不过一个是全量更新一个是部分更新。
PATCH /novel/{novelId}/chapter/{id}/publish
PATCH /novel/{novelId}/chapter/{id}/rename
虽然说可以通过指定专用的动作来进行区分,但是通常可读性较差,无法很快的得知接口对应的业务含义。并且当业务比较多的时候,通过指定专用动作去给接口命名,很快就会出现名称不够用、无法想到见名知意的动作标识。
又比如下面这种情况,现在需要删除章节,业务上将章节进行软删除,先放入回收站,到期之后在进行物理删除。
那么此时接口就不可以使用 DELETE 请求了,因为 DELETE 请求是需要业务在数据库上进行物理删除的,但在实际业务中我们并没有进行删除,这样就会出现问题。
如果使用 POST 请求且不遵循 RESTful 风格设计的话就不会出现这种问题。
POST /novel/create_chapter # 创建章节
POST /novel/rename_chapter # 修改章节名称
POST /novel/publish_chapter # 发布章节
POST /novel/delete_chapter # 逻辑删除章节
POST /novel/permanently_delete_chapter # 物理删除章节
通过这种接口命名方式,对于前后端来说,就能起到见名知意的作用,即使没有详细的接口文档,也可以通过 URL 的命名就可以知道具体是做什么业务的,可维护性就比较强,
四、总结
RESTful 风格作为一种 API 的接口设计风格,并不是一种规范,并且它的接口命名含义通常不明确,当业务比较复杂、繁多的时候就会出现无法表达出清晰、简洁、高效的接口命名。
在实际开发的过程中,我们应该使用更适合自己团队的方式进行开发,清晰、准确的接口命名才是最重要的,而不是一味教条的去遵守某种规范,这样反而会出现适得其反的效果。
参考文章
[1]RESTful 风格中四种请求方式的区别及幂等性分析
[2]为什么删除的请求要使用POST或者DELETE
1336

被折叠的 条评论
为什么被折叠?



