优雅的书写规范化接口文档

发布时间 2024-01-01 18:44:08作者: mharvay

引文

  说到接口文档,大家应该Swagger、Postman、Apifox、ApiPost等一点都不陌生。每个部门应该已经有了自己独立的一套,亦或许每个人有了自己专属的一套,不管那个,往长远考虑,好的接口文档不只是为了自己服务,也是为了将来他人服务,没了接口文档就好比没有目录的书籍,可望而不可读。

个人理解接口文档莫过于以下6点:①、接口的负责人、简单概述以及每次变更的说明;②、接口的请求方式及地址;③、接口的参考文档资料;④、接口的入参和出参;⑤、接口的处理逻辑;⑥、接口的响应状态码说明

详述

1、接口的负责人、简单概述以及每次变更的说明

接口最主要的莫过于谁负责该接口的定义了,连谁负责的都不知道,那后面就没法聊了【Over】。知道了负责人后肯定得知道该接口是干什么用的,它的主要功能是什么,简单概述后,阅读者方可第一时间把握接口情况,随着版本逐步迭代,接口也会相应的进行调整,备注说明好每一次的变更内容(也可增加版本号进行维护),对谁都友好,避免后期维护给他人造成和预期不符

例如:

 变更日期变更内容说明
张美丽 2021-12-11 xxx需求-初次新建接口文档
李铁柱 2022-08-19 xxx需求-增加入参pin的独立校验
王富贵 2023-10-10 xxx需求-增加出参requestId

2、接口的请求方式及地址

2.1、请求方式

请求方式的选择取决于你接口准备做什么事情,查询操作那肯定GET方式,新增或者修改大家往往都习惯用POST方式处理,虽然没啥毛病,但建议能分开还是分开(新增用POST、修改用PUT),删除操作有点独特,其实有两种方式:一种【物理删除】,这种会真正的把后台数据删掉,此种建议使用DELETE方式,另一种是【逻辑删除】,说白了就是修改数据,这一种比较常见,因为想保留一些历史痕迹,此种建议PUT方式

请求方式描述
GET 获取数据
POST 新增数据
PUT 更新数据
DELETE 删除数据

2.2、请求URL

请求URL的定义:建议由指定前缀 + 模块名 + 方法名构成。前缀通常定义有规律、通用、统一,方便进行特殊处理(例如全局拦截等)。模块名通常以业务模块为场景进行定义(例如用户模块user、登录模块login、部门模块dept等)。方法名通常见名知意(切记符合规范化定义,不要随意起名,可参考阿里规约命名)

 

例如:

“/api/user/getUserInfoByPin”来表示通过pin获取用户信息

“/api/user/removeUserById”来表示通过id移除用户信息

3、接口的参考文档资料

平时编写文章或者发布论文你都会参考一些资料,更何况写接口文档呢,必备资料一项都不能少:需求文档地址、依赖外部接口说明地址,其他例如增加一些安全手册地址、系统使用说明地址等等

例如:

小程序需求文档地址:https://www.xxx.xx.x

依赖外部接口文档地址:https://www.xxx.xx.x

小程序系统引导手册:https://www.xxx.xx.x

4、接口的请求头、入参和出参

4.1、请求头

例如:

请求头请求内容说明
Accept application/json 客户端接收的数据格式
Content-Type application/json 请求的报文格式
Cookie cookie信息 一般有登录态的需要

4.2、入参

入参的定义不要一词多用,入参的限制一定要严格校验。入参的定义往往由参数名、参数含义、参数类型、是否必填、参数说明(参数长度限制、范围限制、示例值等)组成,入参信息的多寡备注最终决定了用户在使用 API 接口时的体验感入参定义好之后最好给出对应的入参示例,方便前端同学很直观的把控入参结构,更好地调试 API

例如:

{
    "name": "刘美丽",
    "age": 18,
    "sex": "女",
    "phone": "18812345678"
}

4.3、出参

秉持一个原则:最小数据返回,多余的冗余字段一定程度上会影响接口的性能,所以应该尽量保持数据的冗余程度最低(即接口的单一性),每一个出参的含义和作用都应说明清楚。往往出参伴随着响应体模型的诞生,Result<T>这个大家应该不陌生了,里面通常包含code(状态码)、msg(提示信息)、success(成功标记)、data(数据)四部分。同理,出参定义好之后最好给出对应的出参成功示例和失败示例,这也是出参中重要的一环,方便前端同学很直观的把控出参结构,更好地调试 API

例如:

{
    "code": 200,
    "msg": "成功",
    "success": true,
    "data": {
        "userInfo": {
            "userName": "",
            "userSex": ""
        },
        "deptInfo": {
            "deptName": "",
            "deptCode": ""
        }
    }
}

5、接口的处理逻辑

这一点说白了就是要求后端同学把自己编写该接口的逻辑用白话文大体描述出来,因为每个人习惯不同,可能有些人编写接口时不喜欢写注释信息,有些人可能写了,写到文档上的好处就是可以方便他人查看接口文档时,大致了解你的接口实现思路,同时可以避免不写注释的你后期因遗忘而绞尽脑汁(?或者你是个大佬,后面离开项目组,新的小白不好上手)

例如:

第①步:获取参数并进行参数校验(非空、长度、格式等);

第②步:根据入参xxx调用外部依赖接口xxx进行数据查询操作;

第③步:将②查询结果进行处理,封装返回给前端响应。

6、接口的响应状态码说明

想要实现好的交互方式,响应状态码的控制是离不开的,成功和失败是两大主要方向,失败的场景如果不做处理直接反馈给用户,那是相当不友好的,想处理那就得前后端约定好各种失败场景对应的错误码,一方面可以友好的交互给用户,另一方面可以让研发小哥哥快速定位程序问题。切记一点要把所有可能出现的场景状态码都覆盖到,避免出现遗漏的直接反馈给前端处理(前端如果没处理,那可能用户看到的就是一串长长的红色内容浮现在眼前了,一看这程序就很不专业?)

例如:

状态码提示信息说明
200 成功 请求成功,正常拿到数据
500 系统繁忙,请稍后再试 服务挂掉、NPE、超时等
10001 姓名不能为空、姓名长度超过限制等 参数错误(入参为空、入参格式不正确等)

示例

好的接口文档示例有很多,这里只随机列举了两种:

注意

⚠️⚠️⚠️具体接口的细节其实还有很多,比如接口的鉴权校验、越权校验、调用频率、防刷校验、降级策略、引入依赖版本等,这些其实都是依据具体需求场景而定,亦是不可忽略的一部分。