Golang-Swagger使用问题求助

Golang-Swagger使用问题求助 大家好,

我相对来说是Go语言的新手,刚完成了Coursera上的Go语言专项课程。我正在尝试使用Go-Swagger来完成以下任务:

编写一个swagger.yml文件,包含你的端点、请求和响应的规范(例如:http://localhost:8080/api/v1/repos)

  • id、名称、包含所有者的全名 --> 登录名、URL、HTML URL
  • 使用上述编写的swagger.yml文件生成服务器代码
  • 你需要编写业务逻辑来从GitHub仓库获取信息并将响应返回给客户端
  • 为你的代码编写单元测试
  • 测试覆盖率必须超过80%

我对这些说明感到非常困惑,不知道从何开始。我知道这应该是一个简单的程序,创建一个Swagger服务器,访问包含JSON的端点,解析数据并仅检索必要的信息,然后打印到提供的端点

  • 我需要关于从何处开始以及如何开始的帮助/澄清。谢谢!

更多关于Golang-Swagger使用问题求助的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang-Swagger使用问题求助的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


以下是针对你使用 Go-Swagger 的步骤的详细解答。我将逐步解释如何创建 swagger.yml 文件、生成服务器代码、实现业务逻辑、编写单元测试,并确保测试覆盖率超过 80%。所有代码示例基于 Go 语言和 go-swagger 工具。

步骤 1: 创建 swagger.yml 文件

首先,定义一个 Swagger/OpenAPI 规范文件 swagger.yml,描述你的 API 端点、请求和响应。这里,我们定义一个 GET 端点 /api/v1/repos,用于获取 GitHub 仓库信息。响应包括 id、名称、所有者的登录名、URL 和 HTML URL。

创建 swagger.yml 文件:

swagger: "2.0"
info:
  title: "GitHub Repos API"
  version: "1.0.0"
host: "localhost:8080"
basePath: "/api/v1"
schemes:
  - "http"
paths:
  /repos:
    get:
      summary: "获取 GitHub 仓库信息"
      responses:
        200:
          description: "成功响应"
          schema:
            type: "array"
            items:
              $ref: "#/definitions/Repository"
        500:
          description: "服务器内部错误"
definitions:
  Repository:
    type: "object"
    properties:
      id:
        type: "integer"
        example: 12345
      name:
        type: "string"
        example: "example-repo"
      owner:
        type: "object"
        properties:
          login:
            type: "string"
            example: "octocat"
        required:
          - login
      url:
        type: "string"
        example: "https://api.github.com/repos/octocat/example-repo"
      html_url:
        type: "string"
        example: "https://github.com/octocat/example-repo"
    required:
      - id
      - name
      - owner
      - url
      - html_url

这个文件定义了一个 GET 端点 /api/v1/repos,返回一个仓库对象数组,每个对象包含 id、名称、所有者(仅登录名)、URL 和 HTML URL。

步骤 2: 生成服务器代码

使用 go-swagger 工具从 swagger.yml 生成服务器代码。首先,确保安装了 go-swagger(通过 go install github.com/go-swagger/go-swagger/cmd/swagger@latest),然后在项目根目录运行以下命令:

swagger generate server -f swagger.yml

这将生成服务器骨架代码,包括模型、API 处理程序和主文件。生成的文件通常位于 restapimodels 目录中。

步骤 3: 实现业务逻辑

生成代码后,你需要实现业务逻辑来从 GitHub API 获取仓库信息。编辑生成的 restapi/operations/repos_get.go 文件中的 GetRepos 处理函数。

首先,定义一个结构体来匹配 GitHub API 的响应(注意:GitHub API 返回的字段可能更多,我们只提取所需字段)。在 models 目录中,生成代码已基于 swagger.yml 创建了 Repository 模型,但你可能需要扩展它以处理外部 API 调用。

restapi/operations/repos_get.go 中,修改 GetRepos 函数:

package operations

import (
	"encoding/json"
	"net/http"

	"github.com/go-openapi/runtime/middleware"
	"github.com/your-project/models"
)

// GetReposHandler 处理获取仓库的逻辑
type GetReposHandler struct{}

// Handle 实现处理函数,调用 GitHub API 并返回数据
func (h *GetReposHandler) Handle(params GetReposParams) middleware.Responder {
	// 调用 GitHub API 获取仓库数据
	resp, err := http.Get("https://api.github.com/users/octocat/repos")
	if err != nil {
		return NewGetReposDefault(500).WithPayload(&models.Error{Code: 500, Message: err.Error()})
	}
	defer resp.Body.Close()

	// 解析 GitHub API 响应
	var githubRepos []struct {
		ID      int    `json:"id"`
		Name    string `json:"name"`
		Owner   struct {
			Login string `json:"login"`
		} `json:"owner"`
		URL     string `json:"url"`
		HTMLURL string `json:"html_url"`
	}
	if err := json.NewDecoder(resp.Body).Decode(&githubRepos); err != nil {
		return NewGetReposDefault(500).WithPayload(&models.Error{Code: 500, Message: err.Error()})
	}

	// 转换为 Swagger 模型
	var repos []*models.Repository
	for _, gr := range githubRepos {
		repo := &models.Repository{
			ID:   int64(gr.ID),
			Name: &gr.Name,
			Owner: &models.Owner{
				Login: &gr.Owner.Login,
			},
			URL:     &gr.URL,
			HTMLURL: &gr.HTMLURL,
		}
		repos = append(repos, repo)
	}

	return NewGetReposOK().WithPayload(repos)
}

restapi/configure_api.go 中注册这个处理函数:

api.ReposGetHandler = operations.GetReposHandler{}

步骤 4: 编写单元测试

为你的业务逻辑编写单元测试,使用 Go 的 testing 包。创建一个测试文件,例如 restapi/operations/repos_get_test.go,模拟 HTTP 请求并验证响应。

示例测试代码:

package operations

import (
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/go-openapi/strfmt"
	"github.com/stretchr/testify/assert"
	"github.com/your-project/models"
)

func TestGetReposHandler_Handle(t *testing.T) {
	// 创建一个模拟的 GitHub API 服务器
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusOK)
		json.NewEncoder(w).Encode([]struct {
			ID      int    `json:"id"`
			Name    string `json:"name"`
			Owner   struct {
				Login string `json:"login"`
			} `json:"owner"`
			URL     string `json:"url"`
			HTMLURL string `json:"html_url"`
		}{
			{
				ID:   1,
				Name: "test-repo",
				Owner: struct {
					Login string `json:"login"`
				}{Login: "testuser"},
				URL:     "https://api.github.com/repos/testuser/test-repo",
				HTMLURL: "https://github.com/testuser/test-repo",
			},
		})
	}))
	defer server.Close()

	// 临时替换 GitHub API URL 为模拟服务器 URL
	originalURL := "https://api.github.com/users/octocat/repos"
	// 注意:在实际代码中,你可能需要重构以使用可配置的 URL,这里仅用于测试示例
	// 假设我们通过环境变量或配置设置 URL,这里简化处理
	// 在测试中,我们直接使用 server.URL
	handler := &GetReposHandler{}
	params := GetReposParams{}

	// 调用处理函数
	responder := handler.Handle(params)

	// 验证响应
	assert.IsType(t, &GetReposOK{}, responder)
	okResp := responder.(*GetReposOK)
	assert.Len(t, okResp.Payload, 1)
	assert.Equal(t, int64(1), okResp.Payload[0].ID)
	assert.Equal(t, "test-repo", *okResp.Payload[0].Name)
	assert.Equal(t, "testuser", *okResp.Payload[0].Owner.Login)
	assert.Equal(t, "https://api.github.com/repos/testuser/test-repo", *okResp.Payload[0].URL)
	assert.Equal(t, "https://github.com/testuser/test-repo", *okResp.Payload[0].HTMLURL)
}

运行测试并检查覆盖率:

go test -v ./restapi/operations -cover

为了达到超过 80% 的覆盖率,确保测试覆盖所有分支,包括错误情况(如 GitHub API 调用失败)。你可以添加更多测试用例,例如模拟 HTTP 错误或无效 JSON 响应。

步骤 5: 运行和测试

启动服务器:

go run cmd/github-repos-server/main.go --port=8080

使用 curl 或浏览器测试端点:

curl http://localhost:8080/api/v1/repos

你应该看到返回的仓库信息 JSON 数组。

通过以上步骤,你可以完成从 Swagger 规范到实现和测试的整个流程。如果有具体错误,请提供更多细节以便进一步调试。

回到顶部