Golang微服务中间件允许任何类型,但对端点要求严格
golang是个新手,但我想做的是让我的日志中间件通用化,例如允许任何类型,然后调用下一层的方法 下面是loggingmiddleware包,我希望能够接受任何类型并将其打印出来Golang微服务中间件允许任何类型,但对端点要求严格,go,Go,golang是个新手,但我想做的是让我的日志中间件通用化,例如允许任何类型,然后调用下一层的方法 下面是loggingmiddleware包,我希望能够接受任何类型并将其打印出来 package loggingmiddleware import ( "context" "time" gokitlogger "github.com/go-kit/kit/log" ) type layer interface { Run(context.Context, int
package loggingmiddleware
import (
"context"
"time"
gokitlogger "github.com/go-kit/kit/log"
)
type layer interface {
Run(context.Context, interface{}) (interface{}, error)
}
type LoggingMiddleware struct {
Logger gokitlogger.Logger
Layer layer
}
func (mw LoggingMiddleware) Run(ctx context.Context, i interface{}) (output interface{}, err error) {
defer func(begin time.Time) {
mw.Logger.Log(
"method", "name of method",
"input", i,
"output", output,
"err", err,
"took", time.Since(begin),
)
}(time.Now())
output, err = mw.Layer.Run(ctx, i)
return
}
但是,我希望在调用下一个方法时要严格,如果它需要是string,我希望将类型设置为string,而不是interface{}
在我的示例中,我希望确保只有float64类型将用作参数
type mathServiceInterface interface {
Run(context.Context, float64) (float64, error)
}
type mathService struct{}
func (mathService) Run(_ context.Context, f float64) (float64, error) {
return f * f, nil
}
然而,在我当前的实现中,我得到了这个错误
# github.com/jakelacey2012/blankit/blankit-ms/sqaure
./main.go:92: cannot use ms (type mathServiceInterface) as type loggingmiddleware.layer in field value:
mathServiceInterface does not implement loggingmiddleware.layer (wrong type for Run method)
have Run(context.Context, float64) (float64, error)
want Run(context.Context, interface {}) (interface {}, error)
./main.go:92: cannot use loggingmiddleware.LoggingMiddleware literal (type loggingmiddleware.LoggingMiddleware) as type mathServiceInterface in assignment:
loggingmiddleware.LoggingMiddleware does not implement mathServiceInterface (wrong type for Run method)
have Run(context.Context, interface {}) (interface {}, error)
want Run(context.Context, float64) (float64, error)
我理解这个错误,但是我不知道我的实现是否过于复杂,因为我不知道该怎么做
我希望我所说的有道理,我不知道该给这个标题写什么,所以请随意编辑
另外,如果您需要更多代码来更好地解释,请务必让我知道。这些代码将被称为什么?在某一点上,存在一个实际的使用者,并且该使用者(可能基于您的代码)将使用一个接口(或者
层
或者一个相同的接口)。如果存在中间件,那么该接口必然与中间件一样通用-即,将接口{}
作为运行的参数。因此,让下游的东西更具体(除了你所看到的不编译之外)没有任何意义:实际的使用者不会看到更具体的接口,它会看到运行(上下文,接口{})(接口{},错误)
将如何调用这些?在某一点上,存在一个实际的使用者,并且该使用者(可能基于您的代码)将使用一个接口(或者层
或者一个相同的接口)。如果存在中间件,那么该接口必然与中间件一样通用-即,将接口{}
作为运行的参数。因此,让下游的东西更具体(除了你所看到的不编译之外)没有任何意义:实际的使用者不会看到更具体的接口,它会看到运行(上下文,接口{})(接口{},错误)
错误消息说明了一切,对于实现接口的类型,其方法必须与接口定义的方法完全匹配
遗憾的是,这意味着您的系统无法按设计工作。您需要使用接口{}
并在端点断言实际类型,或者需要为每个类型使用单独的接口(和记录器函数)。错误消息说明了一切,对于实现接口的类型,其方法必须与接口定义的方法完全匹配
遗憾的是,这意味着您的系统无法按设计工作。您可能需要使用接口{}
并在端点断言实际类型,或者需要为每种类型使用单独的接口(和记录器函数)。您所说的有道理,我只是试图避免编写记录器函数,这些函数实际上是相同的代码(在我的头脑中)谢谢你的回答:)你说的很有道理,我只是尽量避免写日志函数,这些函数实际上是相同的代码(在我的头脑中)谢谢你的回答:)好的,我想我是在听你说的,如果我想说得具体一点,我也需要在中间做。如果我是,那么我需要为我将拥有的每个不同接口创建一个不同的日志中间件?是的,或者让它一直通用。你会怎么做?在不知道你在做什么的情况下,这真的很难说,但我的直觉告诉我,如果你处于这种情况,中间件不是最好的方法。中间件在HTTP服务器这样的情况下工作,每个处理程序都是相同的。好吧,我想我是按照你说的去做的,如果我想说得具体一点,我也需要在中间件中做。如果我是,那么我需要为我将拥有的每个不同接口创建一个不同的日志中间件?是的,或者让它一直通用。你会怎么做?在不知道你在做什么的情况下,这真的很难说,但我的直觉告诉我,如果你处于这种情况,中间件不是最好的方法。中间件在HTTP服务器这样的情况下工作,其中每个处理程序都是相同的。