技术改变世界,前后协同变革 自动化 ORM 可靠度高达 99.85%

2019 年 5 月 29 日
 TommyLemon

APIJSON 3.5.0-3.5.7 更新内容:

具体见 Release 发布版本

APIJSON 简介

APIJSON 是一种为 API 而生的 JSON 网络传输协议。
简单的增删改查、复杂的查询、简单的事务操作 提供了完全自动化的 API。
能大幅降低开发和沟通成本,简化开发流程,缩短开发周期。
适合中小型前后端分离的项目,尤其是互联网创业项目企业自用项目

多表关联查询、结构自由组合、多个测试账号、一键共享测试用例

自动生成封装请求 JSON 的 Android 与 iOS 代码、一键下载自动生成的 JavaBean

自动保存请求记录、自动生成接口文档,可添加常用请求、快捷查看一键恢复

一键自动接口回归测试,不需要写任何代码(注解、注释等全都不要)

第三方机构对 APIJSON 的代码扫描,测试结果可靠性高达 99.85%

APIJSON 用 SpringBoot 提供了自动化 API,

自动将前端传的 JSON 参数转为 SQL 语句执行并返回结果,

期间自动校验权限、结构、内容,自动防 SQL 注入,

提供自动化的各种 JOIN(INNER, LEFT, RIGHT 等),

还支持多字段排序 order by,多字段分组 group by,聚合函数 having

等几乎所有 MySQL,PostgreSQL,Oracle 的常规功能。

通过自动化 API,前端可以定制任何数据、任何结构!

大部分 HTTP 请求后端再也不用写接口了,更不用写文档了!

前端再也不用和后端沟通接口或文档问题了!再也不会被文档各种错误坑了!

后端再也不用为了兼容旧接口写新版接口和文档了!再也不会被前端随时随地没完没了地烦了!

在线解析

对于前端

对于后端

🏆码云最有价值开源项目 🚀后端接口和文档自动化,前端(客户端) 定制返回 JSON 的数据和结构!

创作不易,GitHub 右上角点 ⭐Star 支持下吧,谢谢^_^

https://github.com/APIJSON/APIJSON

29487 次点击
所在节点    程序员
206 条回复
TommyLemon
2019 年 6 月 1 日
@my8100 0,不需要写任何测试代码, 自动化接口管理平台
http://apijson.org/
提供 前后对比自动化接口测试 和 机器学习自动化接口测试,
都是 不需要写任何代码,不需要配置任何校验规则 的,看视频试试就知道了
TommyLemon
2019 年 6 月 1 日
@my8100 不过我上面说的 0 覆盖率是指业务接口;
https://i.youku.com/apijson

如果是业务层的 远程函数,那就是 100%(自动查询所有远程函数并逐个调用);
如果是 APIJSONORM 库的 远程函数 功能,那也有 80%(覆盖无参数,多参数,除了 boolean 的其它 JSON 类型)
https://github.com/APIJSON/APIJSON/blob/master/APIJSON-Java-Server/APIJSONBoot/src/main/java/apijson/demo/server/DemoFunction.java
my8100
2019 年 6 月 1 日
代码覆盖率是 0 ?还是说这个指标目前是未知数?
TommyLemon
2019 年 6 月 1 日
@my8100 代码覆盖率 0 是指业务接口,直接使用 自动化接口测试即可,
里面已经放了 143 个测试用例(默认业务需求测试账号 60 个,APIJSON CRUD 各种功能测试账号 83 个)
TommyLemon
2019 年 6 月 1 日
@thisisgpy “最主要的是,码云那个证书并没有一毛钱作用。码云上的用户啥水平大家心里没点数么?”
厉害厉害,把您自己拿到的更有价值的东西、你更好的成就 show 给大家看看,让大家都瞻仰下您这位大神
my8100
2019 年 6 月 1 日
“总结这个报告:
总共 10617 行代码,16 个「可能」的 bug,24 个改进建议, (1 - bugs/lines) 高达 99.85% 。
可见 APIJSON 代码非常严谨可靠。”
因为我也是第一次见到这种计算方法,想请教楼主是如何看待这个商业工具的计算结果和传统意义的代码覆盖率之间的关系?这个工具不能顺带输出代码覆盖率吗?
TommyLemon
2019 年 6 月 1 日
@blindpirate APIJSON 提供了全自动化的接口测试,143 个测试用例,在 #176 楼回了
https://v2ex.ih06.com/t/568631#r_7414951
TommyLemon
2019 年 6 月 1 日
@blindpirate @carlclone 两位说我是培训班 /培训机构出来的,我不知道该如何证明不是,
但从法律上来讲,谁主张谁举证,麻烦提供证据,谢谢!
By the way,对于培训班 /机构,我就不发表自己的看法了,以免引战。
TommyLemon
2019 年 6 月 1 日
@my8100 具体你可以下载报告,issue 里提供了链接,还可以去官网看看,issue 里也有官网链接
my8100
2019 年 6 月 1 日
简单看了下报告: “本次分析时间 2018 年 11 月 16 日”, “ 10617 代码行数”, “ 40 总缺陷”, “高危 - 2 严重 - 3 一般 - 11 建议改进 - 24 ”。
似乎没看到“(1 - bugs/lines) 高达 99.85%”。
TommyLemon
2019 年 6 月 1 日
@my8100 最后这个我的总结的 (1 - 16/10617) = 99.85%
而且这 16 个是 [可能] 的 bug,已经确认有几个是误判,并非真的 bug,所以实际上 99.85% 已经“谦虚”过了
TommyLemon
2019 年 6 月 1 日
@TommyLemon 确实是误判为 bug 的报告用例
src/main/java/zuo/biao/apijson/server/AbstractSQLConfig.java: 897 (可信度: 65%)
zuo.biao.apijson.server.AbstractSQLConfig.putWhere(String, Object, boolean)中
AbstractSQLConfig.combine 可能的空指针解引用

对应实际文件
https://github.com/APIJSON/APIJSON/blob/d8cfc9e6be87bd6116ecf8a125a52021f0154761/APIJSON-Java-Server/APIJSONLibrary/src/main/java/zuo/biao/apijson/server/AbstractSQLConfig.java
内方法 AbstractSQLConfig.putWhere 实际上在前面已经用
combine = getCombine();
做了处理,return 的值不会是 null
```java
@NotNull
@Override
public Map<String, List<String>> getCombine() {
List<String> andList = combine == null ? null : combine.get("&");
if (andList == null) {
andList = where == null ? new ArrayList<String>() : new ArrayList<String>(where.keySet());
if (combine == null) {
combine = new HashMap<>();
}
combine.put("&", andList);
}
return combine;
}
```
my8100
2019 年 6 月 1 日
“最后这个我的总结的 (1 - 16/10617) = 99.85%”
好的,明白了。
TommyLemon
2019 年 6 月 1 日
@TommyLemon 确实是误判为 bug 的报告用例 2
src/main/java/zuo/biao/apijson/JSONObject.java: 411 (可信度: 95%)
1 这里比较了 clazz 和 null,说明 clazz 可能为空指针
2 调用 clazz 的 java.lang.Class.getName 方法(使用可疑的空指针)

对应实际文件
https://github.com/APIJSON/APIJSON/blob/d8cfc9e6be87bd6116ecf8a125a52021f0154761/APIJSON-Java-Server/APIJSONLibrary/src/main/java/zuo/biao/apijson/JSONObject.java
内方法
```java
@Override
public Object put(String key, Object value) {
if (value == null) {
Log.e(TAG, "put value == null >> return null;");
return null;
}
if (StringUtil.isEmpty(key, true)) {
Class<?> clazz = value.getClass();
if (clazz == null || clazz.getAnnotation(MethodAccess.class) == null) {
throw new IllegalArgumentException("puts StringUtil.isNotEmpty(key, true) == false" +
" && clazz == null || clazz.getAnnotation(MethodAccess.class) == null" +
" \n key 为空时仅支持 类型被 @MethodAccess 注解 的 value !!!" +
" \n 如果一定要这么用,请对 " + clazz.getName() + " 注解!" +
" \n 如果是类似 key[]:{} 结构的请求,建议用 putsAll(...) !");
}
key = value.getClass().getSimpleName();
}
return super.put(key, value);
}
```
406 行
Class<?> clazz = value.getClass();
Class 是对象声明后就有的,到执行这行前 value 已经判断过,又不会为 null,
所以实际上 clazz 不会为 null,407 行
if (clazz == null || clazz.getAnnotation(MethodAccess.class) == null) {
中 clazz == null 是一个冗余的判断,后面删掉了,实际上 411 行
clazz.getName()
永远不会因为 clazz == null 而导致 throw NullPointerException,
所以这也是一个误判为 bug 的用例。

其它的你自己找吧,太费时间了,我也没有全部都验证过,即便假设只有这两个是误判,那就是
(1 - bugs/lines) = (1 - 14/10617) = 高达 99.868136%
sagaxu
2019 年 6 月 1 日
大家放过楼主吧,以前是好战了些,现在的文案已经很 OK 了
primordial
2019 年 6 月 1 日
支持楼主,我先在个人项目上试用。
TommyLemon
2019 年 6 月 1 日
@primordial 感谢支持 ^_^
TommyLemon
2019 年 6 月 1 日
@sagaxu 哈哈
TommyLemon
2019 年 6 月 1 日
@yinzhili 采用敏捷开发方式,目前就 49 个类,没必要分太多包导致不好找,
杀鸡焉用牛刀,按照场景选择合适的方式就好。
Log 为了不依赖其它库就加了个简单的类,自己的工程里随你用什么方式,
后续也会提供扩展,用户可重写相关方法,自由使用 Log4J 等打印 APIJSONORM 的日志。
TommyLemon
2019 年 6 月 1 日
@polebug 放荣誉(首选得有)、使用的企业 /项目 的开源项目多了去了,连阿里的也是,
这也是为了让用户放心,免得总有人问“这个项目有没有 /有哪些公司在用呢?”之类的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://v2ex.ih06.com/t/568631

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX