[zeromicro/go-zero]API返回不支持除普通结构体、队列(前置兼容,后续考虑废弃)外部的其他数据类型作为响应体

2024-03-05 72 views
4

请问,为什么会考虑废弃仓库?

如果荒废了的话,根据https://go-zero.dev/cn/template.html来实现统一格式的body相应,则那么无法支持Data作为阵列的情况,如下:

{
  "code": 0,
  "msg": "OK",
  "data": [{},{}]
}

你们是否会再考虑考虑?

回答

7

api语法定义时建议都一JSONObject响应,这就是为什么返回不允许并行,基本数据类型等格式,而为什么并行仍然能用,这是并行语法没有严格,有些使用goctl比较早的公司已经定义了这样的文件,因此做出了兼容,将来可能会强制限制。

5

@kevwan @anqiansong 抱歉,我可能表达的不够清晰,我也能理解返回的body一般是JSONObject类型。

这里我详细表达了下我的意思,希望可以一​​起讨论下:

跟你的文档https://go-zero.dev/cn/template.html来实现实现统一格式的body对应,格式如下

{
  "code": 0,
  "msg": "OK",
  "data": {}
}

这里的主体是JSONObject类型,data也是JSONObject类型,我想的是这里是data内存的情况个人认为还是比较常见的。

意思bodyJSONObject类型,但data不一定是JSONObject类型。

而如果按照文档修改模板,如下:

package handler

import (
    "net/http"
    "greet/response"

    {{.ImportPackages}}
)

func {{.HandlerName}}(ctx *svc.ServiceContext) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        {{if .HasRequest}}var req types.{{.RequestType}}
        if err := httpx.Parse(r, &req); err != nil {
            httpx.Error(w, err)
            return
        }{{end}}

        l := logic.New{{.LogicType}}(r.Context(), ctx)
        {{if .HasResp}}resp, {{end}}err := l.{{.Call}}({{if .HasRequest}}req{{end}})
        {{if .HasResp}}reponse.Response(w, resp, err){{else}}reponse.Response(w, nil, err){{end}}

    }
}

简单的一个reponse.Response实现如下:

type (
    responseBody struct {
        Code    int         `json:"code"`
        Message string      `json:"message"`
        Data    interface{} `json:"data"`
    }
)

func Response(w http.ResponseWriter, resp interface{}, err error) {
    if err != nil {
        httpx.Error(w, err) // Or response non-zero as code
        return
    }

    httpx.OkJson(w, &responseBody{
        Code:    0,
        Message: "Success",
        Data:    resp,
    })
}

模板中的resp,逻辑返回的数据不再是整个body了,而是body中某个字段,在这里是data。而同时这个resp数据结构则在api文件中需要定义的。

比如说我们需要返回一个类似如下的数据:

{
  "code": 0,
  "msg": "OK",
  "data": ["id1", "id2"],
}

这个时候,没办法在api中定义结构了

1⃣️储备的返回将被荒废

get /api/resources/() returns ([]string); // 这里将不支持使用 []

2⃣️不支持别名

type MyData []string // 这里又不支持alias
get /api/resources/() returns (MyData); 

这两种都不支持,那么可能需要类似如下这样的定义了:

type MyData {
    Items []string `json:"items"`
}
get /api/resources/() returns (MyData); 

而这样的定义,感觉有点不够优雅,需要多定义一个数据结构,返回的数据结构也需要多一层items

如果支持阿里云,可以如下:

get /api/resources/() returns ([]string); 

以上是我想表达的,希望有空的可以看看,谢谢!

1

任何新闻?

1

这部分设计我也存在疑问?

9

返回的数组类型将被废弃的原因有两点:

  • 通过JSONObject包装,前置在json解析上可以不考虑JSONArray的情况,他们只用基于一个CodeData这样的一个结构体去写Data对应的结构体即可
  • 大部门要返回数组,分页的情况比较多,如果形成情况返回一个数组,而没有页面相关信息,这也无法规范

综上情况,才考虑放弃使用JSONArray

8

@anqiansong 我能理解大部分是返回 JSONObject,也能理解返回 array 中大部分是分页,有 page, count 类似这种。

但是在做抉择的时候,也要给某些情况的一个选择,比如下拉列表框,要获取支持的情况,比如网络,比如版本信息。这种情况下,page, count 类似这种是愚蠢的的,可能数组是更好的选择。

你感觉说的前端在json解析上可以不用考虑JSONArray的case,只是规范问题,而且我上面提到的case也符合这个规范,只是为了统一代码,api中定义的响应只返回部分数据。

是否可以再考虑前置在json解析上可以不用考虑JSONArray的情况 而废弃这个功能? 是否可以给其他情况一种可能,而不是在接口上多一个无用的项目(类似)? 可以考虑是否人为定义(比如公司代码规范)规范合同不能用数组,而不是在框架层面减少这个功能,或者可以有开关可以开启?

8

仔细看了楼上的讨论,感觉把代码规范写到了框架里确实有点多考虑了,估计未来使用的人多了可能会成为一个FQA。(希望未来能有更多的人使用go-zero,加油! )

6

大家这部分现在是怎么解决的哈

7

非常汇总老哥的观点,还有@veezhang的想法,把代码规范写到框架里,有点过了,这部分不同公司前研讨会有自己的想法,不应该把你们公司或者自己的代码规范放进去框架里,造成用这个框架就不能返回纯数据库类型;而且情况喜欢把code和msg放到body里还是只能通过http代码来区分不同的业务,不同的公司,甚至不同的发开之间本来就有不同的意见,希望加速支持纯架构返回,而不是还需要包层

希望归零格局打开,海纳百川

0

感谢大家的反馈!

v1.2.4 版本里会加上。

同时也希望大家能够理解,我们每增加一个功能都会比较精细和节制,因为一旦加上,即使不加,想要去掉都是一件非常困难的事情。

4

进度更新:

  1. 数组已经被支持,我们不会删除这个功能
  2. returns (int)returns (string)将得到支持
1

我发现该returns ([]type)格式仍然不支持

9

goland的goctl插件没有更新吗?使用[]string还是会爆红 图像

2

1.5.3对[]type格式支持吗?