这是我参与2022首次更文挑战的第20天,活动详情查看:2022首次更文挑战
本文为译文,原文链接:www.calhoun.io/moving-towa…
接上一篇,我们继续讲一下遇到编译报错的问题。
在这里你会有一些想法:
- 修改你的中间件来让
UserService
接口返回一个gitlab.User
,而不是github.User
。 - 特意为GitLab创建一个新的鉴权中间件
- 在
AuthMiddleware
创建一个通用的用户类型来允许你的github和gitlab来实现互相切换。
答案: (1) 如果你足够自信你的公司会坚持gitlab,这点可能会行得通。当然,你将需要修改userservice和mocks,但是这个是一次性的修改,也不算太差。 换句话说,你并不知道你的组织会坚持使用gitlab。毕竟,谁能让哥斯拉的攻击,来决定他们的决定进程呢? 这种观点也可能存在问题,如果你的应用程序中的很多代码到处都是依赖了由这个包返回的
github.User
这个类型。 (2) 可以工作,但是看起来有点傻。为什么没有任何逻辑改变的时候,我们需要去重写所有的那些代码和那些单测呢?明确的是就像你一开始期望的那样,必须有一种方式来让这个接口可以工作。毕竟,那个中间件真的不关心user怎么查找的,它只需要一些关键的信息。 所以你决定试一试答案(3)。你将会在mw
包中创建一个User
类型,然后你将会适配器adapter来连接上你创建的GitLab客户端。
package mw
type User struct {
OrgIDs []string
}
type UserService interface {
User(token string) (User, error)
}
就在你写代码的时候,你有了另一种认识;因为你并不真正关心像用户user的ID或者email,你可以把那些字段从那你的mw.User
类型中剔除出去。所有你需要指定的是你真正关心的字段,这样也会更简单和测试。太棒了!
下一步你需要创建一个适配器,所以你开始干了。
// Package adapter probably isn't a great package name, but this is a
// demo so deal with it.
package adapter
type GitHubUserService struct {
Client *github.Client
}
func (us *GitHubUserService) User(token string) (mw.User, error) {
ghUser, err := us.Client.User(token)
if err != nil {
return mw.User{}, err
}
return mw.User{
OrgIDs: ghUser.OrgIDs,
}, nil
}
type GitLabUserService struct {
Client *gitlab.Client
}
func (us *GitLabUserservice) User(token string) (mw.User, error) {
glUser, err := us.Client.User(token)
if err != nil {
return mw.User{}, err
}
return mw.User{
OrgIDs: glUser.OrgIDs,
}, nil
}
你也需要更新你的mock文件,但是这个改起来会很快。
package mock
type UserService struct {
UserFn func(token string) (mw.User, error)
}
func (us *UserService) Authenticate(token string) (mw.User, error) {
return us.UserFn(token)
}
现在你想使用我们的AuthMiddleware
,无论是Github还是Gitlab,你都可以做到像这样:
var myHandler http.Handler
var us mw.UserService
us = &GitLabUserservice{
Client: &gitlab.Client{
Key: "abc-123",
},
}
// This protects your handler
myHandler = mw.AuthMiddleware(us, "my-org-id", myHandler)
诶,我们终于有一个解决方案来完全解耦了。我们可以很简单地在github和gitlab之间切换了。当新的髋关节源控制公司启动时,我们准备跳上这一潮流。
你是否认为到这里就很完美了呢?且听下回分解。