RESTful 接口设计规范-个人总结

RESTful 接口设计规范-个人总结

以下接口规范为个人收集并总结,仅供参考。欢迎提供建议

使用名词,使用HTTP 请求方法

接口中不要出现动词,以及动作。

使用HTTP 请求方法作为动作的表达。常见的CRUD,在HTTP 中都有对应的方法,可参考developer.mozilla.org/zh-CN/docs/...

HTTP 请求方法

表格来自:www.runoob.com/http/http-m...

方法 描述
GET 请求指定的页面信息,并返回实体主体。
HEAD 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头
POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。
PUT 从客户端向服务器传送的数据取代指定的文档的内容。
DELETE 请求服务器删除指定的页面。
CONNECT HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。
OPTIONS 允许客户端查看服务器的性能。
TRACE 回显服务器收到的请求,主要用于测试或诊断。
PATCH 是对 PUT 方法的补充,用来对已知资源进行局部更新 。

有以下几种:GETPOSTPUTDELETEPATCH。与资源相关联的端点的名称必须与应用的操作相关的HTTP方法对应。

text 复制代码
// bad case
GET /get_users
POST /insert_users
PUT /modify_users
DELETE /delete_users

// good case
GET /users
POST /users
PUT /users
DELETE /users

日常开发中不一定能保证完全按照HTTP 请求方法的规范,但至少要保证请求方法使用GET,其他使用POST

全部小写

RFC 3986 将 URI 定义为区分大小写,对于不同环境,大小写 URI 代表不同的路径,为了避免混淆,建议在 URI 中应始终使用小写字母。

bash 复制代码
// bad case
/Users/12345

// good case
/users/12345

使用斜杠 / 表示层次关系

斜杠/ 通常用于资源的所属关系,后面的属于前面的。这点类似面相对象语言中的.

例如:/users/{userId}/address/{userId}属于usersaddress属于{userId}

使用连字符 - 提高可读性

如果有多个单词,首先建议是使用/来区分层级关系,如果无法做到,则建议使用-区分

bash 复制代码
// bad case
/users/{userId}/pendingorders

// good case
/users/{userId}/pending-orders

不要使用下划线_

虽然可以用下划线_ 代替连字符 - 作为分隔符,但有些应用程序的字体,下划线 _ 字符可能会在某些浏览器或屏幕中部分被遮住或完全遮住。

为避免这种混淆,建议使用连字符 - 而不是下划线 _

bash 复制代码
// bad case
/users/{userId}/pending_orders

// good case
/users/{userId}/pending-orders

不用扩展名

除非直接访问文件,或者下载文件,否则不要使用文件扩展名(例如.xlsx

如果需要指定内容的格式,建议使用Content-Type

bash 复制代码
// bad case
/users/{userId}/pending-orders.xlsx

// good case
/users/{userId}/pending-orders
Content-Type:application/vnd.ms-excel;charset=utf-8;

单数还是复数

如果能唯一确定的资源,则用单数,如果不能,则用复数。

如果单复数都行的,则用复数,因为单数也是复数的特殊形式,为了保持兼容与统一,所以建议复数。

bash 复制代码
// bad case
GET /user/{userId}
GET /users?sex=man

// good case
GET /users/{userId}
GET /users/{userId}/address

精简

减少无用信息,提高信息密度,

sql 复制代码
// bad case
GET /service/api/search

// good case
GET /search

不要暴露服务器的技术栈

技术栈包括使用了服务器、中间件、开发语言以及目录和系统结构等。这些建议不要暴露出来,一方面是有安全隐患,另一方面接口使用方也不关心,冗余不符合精简原则

bash 复制代码
// bad case
/cgi-bin/get_user.php?user=100

// good case
/users?user=100

多条件查询(搜索)

多条件查询时,要求使用?拼接参数查询

例如:/users?location=shenzhen&sex=man 查找位于 shenzhen 的并且sex=man的所有用户

到底用时/还是?

  • 只有一个筛选条件,并且能唯一确定对象,则用/,比如/users/{userId}
  • 有多个筛选条件,并且不能唯一确定对象,尤其是多条件搜索的情况,就用?比如/users?sex=man

注意:只有一个筛选条件时,这里说的唯一,不仅包括单一对象,也包括集合

比如

  • URL"/users/2023/"返回的页面为2023年的存档
  • URL"/users/2023/10/"返回的页面为2023年10月的存档
bash 复制代码
// bad case
GET /users/id={userId}
GET /users/{userId}?sex=man

// good case
GET /users/{userId}
GET /users?localtion=shenzhen&sex=man

例子

ruby 复制代码
// 单个条件,唯一确定
https://www.zhihu.com/people/zhihusucks
https://space.bilibili.com/11083481
https://weibo.com/3266943013

// 多个条件(搜索)
https://www.zhihu.com/search?q=123&type=content
https://www.zhihu.com/search?q=123&type=people

分页与排序支持

分页与排序也当做筛选条件放在?后面

  • GET /users?limit=10&offset=0 :分页,从0行开始返回10条。
  • GET /users?limit=10&offset=0&sort=asc&order=title :排序,返回按名称升序排列的文章记录。

如何表示列表

当没有层次关系时(如在列表中),应该使用分号之类的标点符号或者常见的逗号。

例如:/users/{id1},{id2} 访问多个用户资源。

前端路由与域名相同问题

有时候前端的路由地址会与后端的接口相同,会造成困扰、无法区分到底是前端路由还是后端的接口,调试的时候也会很麻烦。

所以建议有两种方案,后端接口后者统一加/api/,或者后端提供的接口统一使用二级域名api.xx.com

状态码

众所周知,HTTP有自己的状态码,比如下述列表,那我们自己的业务的错误码或者状态码,应该直接复用HTTP的状态码,还是自定义呢?

HTTP 状态码分类

表格来源:www.runoob.com/http/http-s...

HTTP 响应状态码由三个数字组成,第一个数字定义了状态码的类型。

响应分为五类:信息响应(100--199),成功响应(200--299),重定向(300--399),客户端错误(400--499)和服务器错误 (500--599):

分类 分类描述
1** 信息,服务器收到请求,需要请求者继续执行操作
2** 成功,操作被成功接收并处理
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求
5** 服务器错误,服务器在处理请求的过程中发生了错误

结论:业务异常不要使用HTTP的状态码,而要统一放在HTTP 200状态码下面,使用自定义的业务状态码。原因如下

下述结论大部分来自:

www.zhihu.com/question/51...

www.zhihu.com/question/31...

如果业务状态码使用HTTP的状态码,那么会有如下问题

排查困难、分工混乱:一般HTTP的错误码(比如404)都是由服务器或者框架层面抛出的,并且大部分公司的运维与业务开发是分开的,运维只关心服务器层面的异常,业务开发只关心业务异常。如果不区分状态码,那么出现一个404的异常,就无法一眼看出来到底是谁的职责,还得进一步爬log,看错误信息才能确定问题,排查问题困难。如果区分的很清楚,则HTTP状态码的问题直接找运维,自定义的业务异常则直接找业务开发,再具体点就是HTTP200的异常去找业务开发,非HTTP200找运维。

扩展性差:HTTP那点状态码支撑不起众多的业务场景,比如404表示找不到,业务中存在多种找不到的情况,比如"用户找不到"、"订单找不到"、"商品找不到"等情况,如果都用404,那排查问题还是很困难。

运营商劫持:非200状态码(比如404、500)可能会被运营商劫持。或者其他开发人员除了200之外的状态码不认识,还有反向代理或者CDN都有可能有问题

接口出参格式

这里可参考Ant Design Pro的统一规范,这里截取一部分

tsx 复制代码
{
    "success": true,
    "data": {},
    "errorCode": "1001",
    "errorMessage": "error message",
    "showType": 2,
    "traceId": "someid",
    "host": "10.1.1.1"
}

参考

developer.mozilla.org/zh-CN/docs/...

restfulapi.net/resource-na...

www.runoob.com/http/http-t...

pro.ant.design/zh-CN/docs/...

www.zhihu.com/question/31...

www.zhihu.com/question/51...

www.zhihu.com/question/31...

相关推荐
千叶寻-36 分钟前
正则表达式
前端·javascript·后端·架构·正则表达式·node.js
小咕聊编程2 小时前
【含文档+源码】基于SpringBoot的过滤协同算法之网上服装商城设计与实现
java·spring boot·后端
追逐时光者8 小时前
推荐 12 款开源美观、简单易用的 WPF UI 控件库,让 WPF 应用界面焕然一新!
后端·.net
Jagger_8 小时前
敏捷开发流程-精简版
前端·后端
苏打水com9 小时前
数据库进阶实战:从性能优化到分布式架构的核心突破
数据库·后端
间彧10 小时前
Spring Cloud Gateway与Kong或Nginx等API网关相比有哪些优劣势?
后端
间彧10 小时前
如何基于Spring Cloud Gateway实现灰度发布的具体配置示例?
后端
间彧10 小时前
在实际项目中如何设计一个高可用的Spring Cloud Gateway集群?
后端
间彧10 小时前
如何为Spring Cloud Gateway配置具体的负载均衡策略?
后端
间彧10 小时前
Spring Cloud Gateway详解与应用实战
后端