在Golang中覆盖另一个模块中的函数。

huangapple go评论90阅读模式
英文:

Override Function from Another Module in Golang

问题

如何在Golang中覆盖另一个模块中创建的函数?

模块A

在一个模块中,我有一个名为NewPersonApiService的函数,完整的代码如下所示:

package openapi

import (
	"context"
	"errors"
	"net/http"
)

// PersonApiService是一个实现PersonApiServicer接口的服务
// 该服务应该为PersonApi API的每个端点实现业务逻辑
// 包括该服务所需的任何外部包或服务
type PersonApiService struct {
}

// NewPersonApiService创建一个默认的API服务
func NewPersonApiService() PersonApiServicer {
	return &PersonApiService{}
}

// ShowPerson - 详细信息
func (s *PersonApiService) ShowPerson(ctx context.Context) (ImplResponse, error) {
	// TODO - 使用此服务方法所需的逻辑更新ShowPerson
	// 将api_person_service.go添加到.openapi-generator-ignore中,以避免在更新open api生成时覆盖此服务实现

	// TODO: 取消下一行的注释以返回Response(200, Person{})或使用其他选项,如http.Ok ...
	// return Response(200, Person{}), nil

	// TODO: 取消下一行的注释以返回Response(0, Error{})或使用其他选项,如http.Ok ...
	// return Response(0, Error{}), nil

	return Response(http.StatusNotImplemented, nil), errors.New("ShowPerson方法未实现")
}

模块B

在另一个模块中,我想要覆盖NewPersonApiService函数。

我可以通过以下方式在另一个模块中调用该函数:

package main

import (
	"log"
	"net/http"

	openapi "build/code/spec/src"
)

func main() {

	log.Printf("服务器已启动")

	PersonApiService := openapi.NewPersonApiService()
	PersonApiController := openapi.NewPersonApiController(PersonApiService)

	router := openapi.NewRouter(PersonApiController)

	log.Fatal(http.ListenAndServe(":8080", router))

}

但是,如果我尝试覆盖该函数,我会得到编译错误,openapi的类型无法解析,以下是我尝试的代码:

package main

import (
	"context"
	"log"
	"net/http"

	openapi "build/code/spec/src"
)

func main() {

	log.Printf("服务器已启动")

	PersonApiService := openapi.NewPersonApiService()
	PersonApiController := openapi.NewPersonApiController(PersonApiService)

	router := openapi.NewRouter(PersonApiController)

	log.Fatal(http.ListenAndServe(":8080", router))

}

func (s openapi.PersonApiService) ShowPerson(ctx context.Context) (openapi.ImplResponse, error) {

	return openapi.Response(200, openapi.Person{}), nil
}

下面是编译错误的图像:

在Golang中覆盖另一个模块中的函数。

附加信息:
我相信模块B正确引用了模块A。

模块A的go.mod文件如下所示:

module build/code/spec

go 1.13

require github.com/go-chi/chi/v5 v5.0.3

模块B的go.mod文件如下所示:

module bakkt.com/boilerplate

go 1.19

replace build/code/spec => ./../build/generated/

require build/code/spec v0.0.0-00010101000000-000000000000

require github.com/go-chi/chi/v5 v5.0.3 // indirect
英文:

How do you override a function created in another module in Golang?

Module A

In one module I have the function NewPersonApiService, the full code is laid out as below:

package openapi

import (
	"context"
	"errors"
	"net/http"
)

// PersonApiService is a service that implements the logic for the PersonApiServicer
// This service should implement the business logic for every endpoint for the PersonApi API.
// Include any external packages or services that will be required by this service.
type PersonApiService struct {
}

// NewPersonApiService creates a default api service
func NewPersonApiService() PersonApiServicer {
	return &PersonApiService{}
}

// ShowPerson - Detail
func (s *PersonApiService) ShowPerson(ctx context.Context) (ImplResponse, error) {
	// TODO - update ShowPerson with the required logic for this service method.
	// Add api_person_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.

	//TODO: Uncomment the next line to return response Response(200, Person{}) or use other options such as http.Ok ...
	//return Response(200, Person{}), nil

	//TODO: Uncomment the next line to return response Response(0, Error{}) or use other options such as http.Ok ...
	//return Response(0, Error{}), nil

	return Response(http.StatusNotImplemented, nil), errors.New("ShowPerson method not implemented")
}

Module B

In a separate module I want to override this NewPersonApiService.

I can call this function in the other module by doing the following:

package main

import (
	"log"
	"net/http"

	openapi "build/code/spec/src"
)

func main() {

	log.Printf("Server started")

	PersonApiService := openapi.NewPersonApiService()
	PersonApiController := openapi.NewPersonApiController(PersonApiService)

	router := openapi.NewRouter(PersonApiController)

	log.Fatal(http.ListenAndServe(":8080", router))

}

But if I try to override the function I get compilation error, unresolved type for openapi, below is what I was attempting to do:

package main

import (
	"context"
	"log"
	"net/http"

	openapi "build/code/spec/src"
)

func main() {

	log.Printf("Server started")

	PersonApiService := openapi.NewPersonApiService()
	PersonApiController := openapi.NewPersonApiController(PersonApiService)

	router := openapi.NewRouter(PersonApiController)

	log.Fatal(http.ListenAndServe(":8080", router))

}

func (s openapi.PersonApiService) ShowPerson(ctx context.Context) (openapi.ImplResponse, error) {

	return openapi.Response(200, openapi.Person{}), nil
}

Below is an image of the compilation error

在Golang中覆盖另一个模块中的函数。
Additional Info:
I believe Module B is properly referencing Module A.

Module A's go.mod file reads as follows:

module build/code/spec

go 1.13

require github.com/go-chi/chi/v5 v5.0.3

Module B's go.mod file reads as follows:

module bakkt.com/boilerplate

go 1.19

replace build/code/spec => ./../build/generated/

require build/code/spec v0.0.0-00010101000000-000000000000

require github.com/go-chi/chi/v5 v5.0.3 // indirect

答案1

得分: 0

解决方案是在另一个模块中实现ShowPerson方法,你需要创建一个新的类型,实现PersonApiServicer接口,并提供自己的ShowPerson方法的实现。

在模块B中运行这个代码可以工作,并允许你更改在模块A中定义的API调用的响应。

package main

import (
	"context"
	"log"
	"net/http"

	openapi "build/code/spec/src"
)

type MyPersonApiService struct{}

func NewMyPersonApiService() openapi.PersonApiServicer {
	return &MyPersonApiService{}
}

func (s *MyPersonApiService) ShowPerson(ctx context.Context) (openapi.ImplResponse, error) {
	// TODO: 在这里添加ShowPerson方法的自定义实现。

	// 例如,你可以检索一个人的详细信息,并返回如下:
	person := openapi.Person{Id: 23, Name: "Vark Thins", Age: 20}
	return openapi.Response(http.StatusOK, person), nil
}

func main() {

	log.Printf("服务器已启动")

	PersonApiService := NewMyPersonApiService()
	PersonApiController := openapi.NewPersonApiController(PersonApiService)

	router := openapi.NewRouter(PersonApiController)

	log.Fatal(http.ListenAndServe(":8080", router))

}
英文:

The solution was to implement the ShowPerson method in another module, you would need to create a new type that implements the PersonApiServicer interface and provides its own implementation of the ShowPerson method.

Running this in Module B worked and allowed me to change the response of the API call defined in Module A.

package main

import (
	"context"
	"log"
	"net/http"

	openapi "build/code/spec/src"
)

type MyPersonApiService struct{}

func NewMyPersonApiService() openapi.PersonApiServicer {
	return &MyPersonApiService{}
}

func (s *MyPersonApiService) ShowPerson(ctx context.Context) (openapi.ImplResponse, error) {
	// TODO: Add your own implementation of the ShowPerson method here.

	// For example, you could retrieve a person's details and return them as follows:
	person := openapi.Person{Id: 23, Name: "Vark Thins", Age: 20}
	return openapi.Response(http.StatusOK, person), nil
}

func main() {

	log.Printf("Server started")

	PersonApiService := NewMyPersonApiService()
	PersonApiController := openapi.NewPersonApiController(PersonApiService)

	router := openapi.NewRouter(PersonApiController)

	log.Fatal(http.ListenAndServe(":8080", router))

}

</details>



huangapple
  • 本文由 发表于 2023年2月16日 01:04:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/75463166.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定