APIJSON icon indicating copy to clipboard operation
APIJSON copied to clipboard

建议:在输入引用赋值顺序错误时给出更明显的提示

Open jerrylususu opened this issue 4 years ago • 2 comments

引用赋值需要请求中先出现原始值,然后才能被引用,如果顺序相反则引用无法成功。但是在使用 Request 表对输入进行校验时,引用赋值出现的位置(Request 表中)和用户实际使用的位置(POST 请求体)并不相同,在用户请求中因为顺序错误导致引用赋值失败时,给出的错误提示不够明显,导致排错十分困难。希望能给出更明显的提示。

问题场景:APIJSONBoot 示例项目中,有 User, Privacy 两表,其中用户注册时,请求会和 Request 表中对应项 (method=POST, tag=register)进行校验,校验规则简化如下,即 user.id 依赖于 privacy.id

简化后的依赖关系

{
  "User": {
    "UPDATE": {"id@": "Privacy/id"}
  },
  "Privacy": {}
}

在实际发起请求的时候,Requestbody 中需要 Privacy 在上,User 在下,如果顺序反过来,用户注册本身不会成功(数据库中无写入操作),但是请求显示正常完成(code=200)。

错误请求例(method=POST, addr=/post)

{
    "User": {
        "name": "test"
    },
    "Privacy": {
        "phone": "13323332338",
        "_password": "testpwd"
    },
    "verify": "9816",
    "tag": "register"
}

此情况下返回值(返回200,但 sql.execute 为0)

{
    "ok": true,
    "code": 200,
    "msg": "success",
    "sql:generate|cache|execute|maxExecute": "0|0|0|200",
    "depth:count|max": "1|5",
    "time:start|duration|end": "1627506120546|7|1627506120553"
}

jerrylususu avatar Jul 28 '21 21:07 jerrylususu

这一问题在使用 /register 端点的时候同样存在,但因为一部分处理操作包在了方法体内部(例如 parseResponse(requestObject)),使得找出问题原因更加困难。

以相同输入,POST /register 得到的返回值(实际用户注册是失败的)

{
    "ok": true,
    "code": 200,
    "msg": "success"
}

如果输入顺序正常,正常的返回

{
    "privacy": {
        "ok": true,
        "code": 200,
        "msg": "success",
        "count": 1,
        "id": 1627508021086
    },
    "user": {
        "ok": true,
        "code": 200,
        "msg": "success",
        "count": 1,
        "id": 1627508021086
    },
    "verify": "6533",
    "ok": true,
    "code": 200,
    "msg": "success"
}

jerrylususu avatar Jul 28 '21 21:07 jerrylususu

原因:引用赋值查不到对应被引用的值时,只是终止处理当期对象。

规范是必须按照顺序来,但是 Request 表中配置的 json 类型 structure 会被 MySQL 强制自动按 ASCII 编码排序,只能提供文档说明顺序。

如果要直接从代码上保证,应该对 AbstractObjectParser. onParse 385 和 395 行两个 if 中加上判断 method == POST || method == PUT 时 throw UnsupportedException("引用赋值 " + path + "/" + key + ": " + targetPath + " 解析失败,POST 和 PUT 接口必须保证每个对象执行都成功!")

https://github.com/Tencent/APIJSON/blob/3ccd9674ce572e36907dd961ae9386e31abc2483/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java

image

这个影响不大,暂时没时间去修改和测试,你可以提个 PR,合并后会把你加入贡献者名单,开源要大家一起共建才会更美好~ https://github.com/Tencent/APIJSON/blob/master/CONTRIBUTING.md image

TommyLemon avatar Jul 31 '21 17:07 TommyLemon