Golang中使用OpenAPITools生成客户端(swagger)遇到问题求助

Golang中使用OpenAPITools生成客户端(swagger)遇到问题求助 大家好,

我正在尝试使用 OpenAPITools 生成的客户端来构建一个 Go 语言的 REST 客户端用例。但到目前为止进展不太顺利。

OpenAPI Tools (github.com)

我想弄清楚,下面遇到的错误是因为我导入生成的客户端时操作有误,还是因为 github 上 openapi-generator 项目中那 3544 个未解决的问题导致的?

  1. 我使用最新的可用 .jar 文件生成了客户端。
  2. 将输出文件夹复制到了我的 Go 工作文件夹的根目录下。(工作文件夹/go-client)
  3. 在我的主模块的 go.mod 文件中添加了一行 replace 指令,将 go-client 模块指向 go-client 文件夹(工作文件夹/main-module)
  4. 在主模块文件夹中执行了 go get go-client,以便将其作为依赖项添加到 go.mod 文件的 require 部分中(我对于如何添加依赖项还是有些困惑)

这使得智能感知(VSCode)能够找到 go-client 文件夹中的所有内容,所以我当时还挺高兴的。:smiley:

在我主模块的 main 函数中,我尝试使用生成的 api-client 调用一个端点。不幸的是,我在生成的 go-client 模块中遇到了一些构建错误,形式是几个“undefined: Object”和三个“undefined: os”。

我哪里做错了?还是说这个客户端生成器本身就有问题?

任何建议都感激不尽。

此致,

molotch


更多关于Golang中使用OpenAPITools生成客户端(swagger)遇到问题求助的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中使用OpenAPITools生成客户端(swagger)遇到问题求助的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


根据你的描述,问题很可能出在生成的客户端代码本身。OpenAPITools的Go生成器确实存在一些已知问题,特别是对Object类型和os包的处理。以下是具体分析和解决方案:

问题分析

  1. undefined: Object - 这是OpenAPI生成器在处理object类型时的常见问题,生成器有时会错误地生成Object而不是正确的Go类型
  2. undefined: os - 可能是导入缺失或命名冲突

解决方案

1. 检查并修复生成的代码

首先检查生成的代码中Object出现的位置:

// 在生成的代码中搜索 "Object" 类型
// 通常出现在类似这样的地方:
type SomeResponse struct {
    Data Object `json:"data"`  // 错误:应该是 interface{} 或具体类型
}

// 应该修复为:
type SomeResponse struct {
    Data interface{} `json:"data"`  // 或者 map[string]interface{}
}

2. 检查导入语句

查看生成的代码中是否有缺失的os包导入:

// 在生成的代码文件顶部检查导入
import (
    "bytes"
    "context"
    "encoding/json"
    "encoding/xml"
    "errors"
    "fmt"
    "io"
    "mime/multipart"
    "net/http"
    "net/url"
    "os"  // 确保这行存在
    "path/filepath"
    "reflect"
    "regexp"
    "strconv"
    "strings"
    "time"
    "unicode/utf8"
)

3. 使用修复脚本

创建一个修复脚本来自动修复常见问题:

// fix_generated.go
package main

import (
    "io/ioutil"
    "log"
    "os"
    "path/filepath"
    "strings"
)

func main() {
    err := filepath.Walk("./go-client", func(path string, info os.FileInfo, err error) error {
        if err != nil {
            return err
        }
        
        if !info.IsDir() && strings.HasSuffix(path, ".go") {
            content, err := ioutil.ReadFile(path)
            if err != nil {
                return err
            }
            
            // 修复 Object 类型
            fixed := strings.ReplaceAll(string(content), "Object", "interface{}")
            
            // 确保 os 包导入
            if strings.Contains(fixed, "os.") && !strings.Contains(fixed, `"os"`) {
                // 在适当位置添加导入
                lines := strings.Split(fixed, "\n")
                for i, line := range lines {
                    if strings.HasPrefix(line, "import (") {
                        // 在 import 块中添加 os
                        for j := i + 1; j < len(lines); j++ {
                            if strings.Contains(lines[j], `"`) && !strings.Contains(lines[j], `"os"`) {
                                lines[j] = `    "os"` + "\n" + lines[j]
                                break
                            }
                        }
                        fixed = strings.Join(lines, "\n")
                        break
                    }
                }
            }
            
            err = ioutil.WriteFile(path, []byte(fixed), 0644)
            if err != nil {
                return err
            }
        }
        return nil
    })
    
    if err != nil {
        log.Fatal(err)
    }
}

4. 使用替代的生成选项

尝试不同的生成器或选项:

# 使用不同的生成器
java -jar openapi-generator-cli.jar generate \
    -i openapi.yaml \
    -g go \
    -o ./go-client \
    --additional-properties=packageName=client \
    --additional-properties=isGoSubmodule=true

# 或者使用experimental的生成器
java -jar openapi-generator-cli.jar generate \
    -i openapi.yaml \
    -g go-experimental \
    -o ./go-client

5. 手动修复示例

如果自动修复不成功,手动查找并修复:

# 查找所有包含 Object 的文件
grep -r "Object" ./go-client --include="*.go"

# 查找所有使用 os 包但未导入的文件
grep -r "os\." ./go-client --include="*.go" | grep -v '"os"'

6. 临时解决方案

如果问题持续存在,可以考虑:

// 在你的代码中重新定义缺失的类型
type Object = interface{}

// 或者在生成后手动添加
// 在生成的代码文件中添加:
// type Object interface{}

7. 验证模块设置

确保你的模块设置正确:

# 在主模块目录中
go mod init your-module-name
go mod edit -replace go-client=../go-client
go mod tidy

这些问题确实是OpenAPITools生成器的已知缺陷。3544个未解决问题中很多都与Go语言生成器相关。建议在修复后考虑提交issue或PR到OpenAPITools项目。

回到顶部