前言
TypeScript + React 类型安全三件套:Component、Redux、和 Service 类型化。
Service 类型化
通用基础方案
规范和基础类型
首先需要明确前后端交互的基本接口规范,例如,所有接口返回数据格式都应该遵循:
interface AjaxResult<R extends any> {
/** 错误码 */
code?: number | null;
/** 描述信息 */
message?: string | null;
/** 数据主体 */
result: R;
}
而对应的,所有接口调用函数应该遵循这样接口定义:
interface AjaxFunction {
(...args: any[]): Promise<AjaxResult<any>>;
}
业务逻辑里需要明确的就是,接口定义里入参和响应数据主体的类型。
示例
举个获取用户信息接口例子,通过后端提供的任意格式的文档,比如 swagger、yapi 甚至 wiki 得知:
- url 是
/api/user/info
- 需传递一个数字类型 get 参数
id
- 返回数据主体是包含数字 id、字符串 name 的一个对象
手写成 TypeScript 调用代码:
/** 后端数据主体 */
interface UserResult {
/** id */
id: number;
/** 英文名 */
name: string;
}
/** 接口调用代码 */
const getUserInfo = (id: number): AjaxResult<UserResult> =>
axios.get("/api/user/info", { id });
sm2tsservice 方案 【will be @tefe/service
】
从前边的例子,可知 Service 类型化真正的痛点在于基于接口文档手写 TypeScript 代码,在已有 swagger 或者 yapi 文档格式化数据的情况下,这无异于重复的人力浪费,找到一套自动化生成技术方案,将极大的提升研发效率。
swagger-codegen
基于 Java 代码注解提取文档的 Swagger 体系里,有提供了全套的 Java 注解、注解解析、文档 UI 界面以及生成各种语言调用代码的技术工具方案 Swagger-Codegen。
该方案支持生成 TypeScript 类型、接口调用代码,其核心数据转换、生成规则如下:
基于以上规则,我们很容易发现,该方案存在以下隐患:
- Tags 注解不为空,变更注解或者注解为空,变更 Controller Name,都会造成 Tags 值变动,进而造成生成的文件名变动;
- API 注解不为空,注解重复或者注解为空,Method Name 重复,当重复的 Method Name 顺序变更的时候,会造成 operationId 值变动;
- 当 Method 参数顺序发生变更的时候,会造成对应接口调用代码的参数变更。
这些隐患会导致当满足特定条件时,生成的代码会发生不可控的变动,进而导致逻辑错乱,造成十分严重的后果。
sm2tsservice
sm2tsservice 改造了 swagger-codegen,并在此基础上进行了封装,旨在解决业务使用上的痛点:
- 实现 yapi 转 swagger 文档模块,支持 yapi 自动生成接口调用代码
- 制定 swagger 文档编写规范,提升前后端协作效率
- 实现 swagger 文档规范校验、规则校正模块,确保生成代码稳定性
- 实现 swagger 文档增量更新模块,更灵活的控制代码生成
- 实现接口入参、数据返回校验模块,利用 swagger 文档对数据进行校验
yapi 转 swagger 规则
将 yapi 文档转换成 swagger 文档,曲线支持 yapi 自动生成 service 代码,转换规则如下:
swagger 文档规范
接口规范,旨在消除人为造成的不确定性,其中核心条目包括:
swagger 校验、校正模块
校验 swagger 文档是否符合规范,校正 operationId 的生成方式,核心规则如下:
定制 swagger-codegen 代码,修改调用函数格式:
增量更新
将接口文档分为本地和远端版本,本地版本跟随 vcs 进行维护;每次生成代码,会下载远端版本,然后与本地版本进行 diff,将差异已 web 界面的形式显示出来,供选择任意差异、增量更新:
双向校验
提供 proxy 插件,可在联调阶段对接口入参、后端返回,依照对应的 swagger 文档约定进行校验,默认可以打印出不符合约定的接口错误。
More
- sm2tsservive 文档站
- 增量更新技术方案 json-diff
- 代码生成方案 定制 swagger-codegen