Laravel 项目全自动接口管理(接口部分)
简介
本工具旨在通过一个包含简单完备
的接口描述,自动生成接口校验、数据字典和其对应文档
。
本工具包含接口管理和回归测试两部分功能,本文只覆盖接口管理功能。
运作方式
输入 - 模板
↓
输出 - 接口代码、数据字典代码、接口文档、postman文件、客户端代码(暂未支持)、异常响应(i18n暂未支持)
已支持数据类型
标量:Integer, String
枚举:任意自定义的枚举(字符串 / 数字)
模型:包含多个字段的组合类型
数组:同级同结构的数据可以描述为数组
接口:接口类似于模型,但数据需要被标记为Request或Response,用于区分是输入数据还是输出数据。
异常码:全局异常码,可以在接口任意执行阶段抛出,终止执行并返回响应。
示例
接口
假设我们需要一个获取用户历史记录的接口。
该接口使用auth中间件,请求POST,地址为http://{{host}}/api/v1/xxxxx/get_class_histories
请求参数为年月和分页的页数,都为可选参数,响应为ClassRecord的数组。
class Xxxxx {
/**
* 获取历史记录,不限制时间区间
* 先搜年月,后根据时间倒序获取分页
*/
@Middleware("auth")
@API(methods = {MethodType.POST})
class GetClassHistories {
/** 不填默认本年 */
@Request
@Optional
Integer year;
/** 不填默认本月 */
@Request
@Optional
String month;
/**
* 第几页
*/
@Request
@Optional
Integer page;
@Response
Models.ClassRecord[] histories;
}
}
模型
在上面的接口中提到了ClassRecord模型
下面为其数据描述,包含多个数据字段,既有标量类型也有枚举和模型。
其中的Optional注解表示该字段可以为null,其他模型略。
class ClassRecord {
Integer id;
/** 注释 */
@Optional
Integer sid;
Integer pay;
Integer useTool;
/** 有时候需要用它搜索 */
Integer beginTime;
/** Y-m-d H:i:s */
String datetimeOfBeginTime;
/** 开始时间周几 */
Enums.DayOfWeek dayOfBeginTime;
/**
* 注释
*/
@Optional
Enums.ClassRecordFreeTry freeTry;
/** 状态 */
Enums.ClassRecordStatus status;
@Optional
Models.Material material;
/** 评价,可以为空 */
@Optional
Models.ClassComment classComment;
@Optional
Enums.ClassType classType;
@Optional
Models.Teacher teacher;
}
枚举
从0开始自增的枚举数据
/** 周几,从周日开始 */
enum DayOfWeek {
SUNDAY,
MONDAY,
TWESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
}
手动指定了value的int枚举
/**
* 用户状态
*/
enum UserStatus implements FixedEnumValueInterface {
INIT(0),
DISABLED(2),
IN_CLASS(4),
;
int value;
UserStatus(int value) {
this.value = value;
}
@Override
public int getValue() {
return value;
}
}
全局错误码
/** 服务器内部错误,等同于500 */
SERVER_INTERNAL_ERROR(-1),
/** 参数不合法 */
INVALID_PARAMETER(-2),
/** 接口已失效,应校验是否是该版本接口已禁用,若已禁用客户端应触发升级提示 */
API_DEPRECATED(-10),
/** 等同于404 */
API_NOT_FOUND(-11),
/** 维护模式 */
MAINTAIN_MODE(-20),
/** 用户未登录 */
AUTH_FAILED(-100),
/** 自定义的ERROR信息 */
CUSTOM_ERROR_MESSAGE(-10000),
依赖
JDK8
php 7.2
laravel 5.7
larecipe
php-parser
由于未发布正式版,请使用composer指定github引入
{
"type": "vcs",
"url": "https://github.com/Kamicloud/api-generator..."
}
建议使用vscode并安装java lang support扩展,他可以提供模板的hint
结果
配置JAVA_HOME环境变量,指向安装的jdk
引入工具和larecipe
执行
php artisan larecipe:install
php artisan generator:install
将所需的文件发布到当前项目中
可以看到resources下generator出现templates、config、defines三个文件夹
templates即接口描述目录,参考已存在的描述设计自己的接口
config中为配置信息,建议使用默认配置
app/bin下是发布后的命令
initGenerator会初始模板解析环境,如果使用composer update进行工具更新,需要重新执行该命令
generate将根据模板生成代码和文档
localhost/docs下为文档目录
app/Http/Services/下为业务代码目录,在$message中获取对应的请求数据和setResponse
$message->setResponse(xxxxxModel::initFromEloquents($xxxx));
接口文档
生成的代码
生成的测试用例文件
# __api: /api/api/v1/xxxxxxxxxx/get_class_histories
__enabled: true
__role: User
__user: 1
__anchor:
__params:
__testcases:
-
__params:
year:
month:
page:
-
__params:
year: 2019
month: 3
page:
-
__params:
year: 2018
month: 12
page:
使用生成的postman调试接口
从Eloquent模型到DTO
\App\Generated\xxxx\xxxModel::initFromEloquent($eloquentModel)
如果对应的key不相同,可以使用@DBField("name")指定映射,如果不指定,默认指向low dash的字段
结语
目前还没想好如何在客户端同步调用接口的代码,所以暂时不支持生成客户端代码。而且服务端在开发时会建立独立的分支,如何让客户端方便的同步其他分支的代码也是要考虑的地方。
本工具还在开发中,募集贡献者,发布正式版前,不建议应用于生产环境
。
本作品采用《CC 协议》,转载必须注明作者和本文链接
为什么要用到java
@zhaomengqiao
比较过openapi和dingo,无论是使用yaml还是php doc,都没有办法做到简洁和准确。
特别是swagger,我用官网的demo复制到vscode,yaml的缩进全都乱了,而且一个接口的描述需要用好几行来完成。
而强类型的编程语言就不会有这方面问题。在做这个工具的时候,有人已经做了一个功能很接近的闭源程序,某种程度上说,也是用java做模板这条路走得通。
也考虑过typescript/python/php,不过因为不支持类嵌套,模板会很丑。
对于java方面,其实已经弱化了他的存在,暴露给使用者的模板完全可以看做单纯的文本。使用的时候也只是配下环境执行脚本,编译和执行我都封装起来了。
另外只使用java做代码生成,校验之类的功能还是在各端代码的基类完成的。
@Kamicloud 厉害,持续关注
golang呢?对java无好感……
@Rming golang做模板不好看啊,而且golang好像没有装饰器/注解这类语法,对于需要描述变量为nullable或者mutable应该会很难做
厉害了,持续关注