「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战」。
B站视频讲解地址
Github源码
3. 接入网关
3.1 proto文件
- api-gateway/services/proto
将我们的user模块的两个proto文件
复制过来,然后同样的操作,生成pb文件。
注意要在api-gateway
中重新生成proto文件
3.2 接入路由
- api-gateway/weblib/router.go
在这个文件中接入gin路由,中间件部分就省略了。
func NewRouter(service ...interface{}) *gin.Engine {
ginRouter := gin.Default()
//使用中间件,接收服务调用实例
ginRouter.Use(middlewares.Cors(), middlewares.InitMiddleware(service), middlewares.ErrorMiddleware())
//使用session中间件
store := cookie.NewStore([]byte("something-very-secret"))
ginRouter.Use(sessions.Sessions("mysession", store))
// 测试连接
v1.GET("pong", func(c *gin.Context) {
c.JSON(200, "success")
})
// 用户服务
v1.POST("/user/register", handlers.UserRegister)
v1.POST("/user/login", handlers.UserLogin)
}
return ginRouter
}
3.3 编写接口
3.3.1 用户注册
- 定义请求参数
var userReq services.UserRequest
- 绑定参数
PanicIfUserError(ginCtx.Bind(&userReq))
- 获取服务实例
userService := ginCtx.Keys["userService"].(services.UserService)
- 调取服务对象
userRes, err := userService.UserRegister(context.Background(), &userReq)
- 返回数据
ginCtx.JSON(http.StatusOK, gin.H{"data": userRes})
- 完整代码
func UserRegister(ginCtx *gin.Context) {
var userReq services.UserRequest
PanicIfUserError(ginCtx.Bind(&userReq))
//从gin.keys取出服务实例
userService := ginCtx.Keys["userService"].(services.UserService)
userRes, err := userService.UserRegister(context.Background(), &userReq)
PanicIfUserError(err)
ginCtx.JSON(http.StatusOK, gin.H{"data": userRes})
}
3.3.2 用户登录
func UserLogin(ginCtx *gin.Context) {
var userReq services.UserRequest
// 定义请求参数
PanicIfUserError(ginCtx.Bind(&userReq))
// 绑定服务
userService := ginCtx.Keys["userService"].(services.UserService)
//从gin.keys取出服务实例
userRes, err := userService.UserLogin(context.Background(), &userReq)
//调用服务端的函数
PanicIfUserError(err)
token, err := util.GenerateToken(uint(userRes.UserDetail.ID))
// 生成token
if err != nil {
userRes.Code = e.ERROR_AUTH_TOKEN
}
ginCtx.JSON(200, gin.H{"code": userRes.Code, "msg": e.GetMsg(userRes.Code), "data": gin.H{"admin": userRes.UserDetail, "token": token}})
// 响应返回
}
3.4 接入etcd
- 定义用户模块微服务实例
etcdReq := etcd.NewRegistry(
registry.Addrs("127.0.0.1:2379"),
)
// 用户
userMicroService := micro.NewService(
micro.Name("userService.client"),
micro.WrapClient(wrappers.NewUserWrapper),
)
//用户服务调用实例
userService := services.NewUserService("rpcUserService", userMicroService.Client())
- 定义http微服务模块实例,使用gin暴露http接口并注册到etcd中
server := web.NewService(
web.Name("httpService"),
web.Address(":4000"),
//将服务调用实例使用gin处理
web.Handler(weblib.NewRouter(userService)), // 把userService微服务实例放入其中
web.Registry(etcdReq),
web.RegisterTTL(time.Second*30),
web.RegisterInterval(time.Second*15),
web.Metadata(map[string]string{"protocol": "http"}),
)
查看是否将http服务注册到etcd,注册成功
3.5 测试
在 user/main.go文件下执行
go run main.go --registry=etcd --registry_address=127.0.0.1:2379
在 api-gateway/main.go下执行
go run main.go --registry=etcd --registry_address=127.0.0.1:2379
- 用户注册
- 用户登录