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

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

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

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

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

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

HTTP 请求方法

表格来自:https://www.runoob.com/http/http-methods.html

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

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

// 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 中应始终使用小写字母。

// bad case
/Users/12345

// good case
/users/12345

使用斜杠 / 表示层次关系

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

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

使用连字符 - 提高可读性

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

// bad case
/users/{userId}/pendingorders

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

不要使用下划线_

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

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

// bad case
/users/{userId}/pending_orders

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

不用扩展名

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

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

// bad case
/users/{userId}/pending-orders.xlsx

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

单数还是复数

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

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

// bad case
GET /user/{userId}
GET /users?sex=man

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

精简

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

// bad case
GET /service/api/search

// good case
GET /search

不要暴露服务器的技术栈

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

// 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月的存档
// bad case
GET /users/id={userId}
GET /users/{userId}?sex=man

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

例子

// 单个条件,唯一确定
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 状态码分类

表格来源:https://www.runoob.com/http/http-status-codes.html

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

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

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

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

下述结论大部分来自:

https://www.zhihu.com/question/513865370/answer/2643896815

https://www.zhihu.com/question/310737821/answer/585641618

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

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

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

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

接口出参格式

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

{
    "success": true,
    "data": {},
    "errorCode": "1001",
    "errorMessage": "error message",
    "showType": 2,
    "traceId": "someid",
    "host": "10.1.1.1"
}

参考

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status

https://restfulapi.net/resource-naming/

https://www.runoob.com/http/http-tutorial.html

https://pro.ant.design/zh-CN/docs/request/#%E7%BB%9F%E4%B8%80%E8%A7%84%E8%8C%83

https://www.zhihu.com/question/31363461

https://www.zhihu.com/question/513865370

https://www.zhihu.com/question/310737821

你可能感兴趣的:(restful,设计规范,后端)