介绍
我们在上一篇文章「Golang 微服务工具包 Go kit」介绍了 Go 语言工具包 Go kit,本文我们介绍怎么基于 Go kit 开发 Web 项目。在阅读上篇文章后,我们已经知道 Go kit 服务分为三层,分别是 transport、endpoint 和 service。
其中,service 层定义业务接口并实现接口方法。
endpoint 层接收请求参数并返回响应结果,需要注意的是,在 endpoint 层,给业务接口方法构建 endpoint.Endpoint。
因为 endpoint.Endpoint 是函数类型,封装一层,方便我们使用 endpoint 装饰器,给 endpoint.Endpoint 添加功能,例如日志、限流、负载均衡、链路追踪等。
endpoint 层使用构建的 endpoint.Endpoint 调用 service 层接口的方法处理请求。
transport 层对外提供调用接口(http 或 rpc)。
基于 Go kit 开发 Web 项目
我们基于 Go kit 开发一个用户中心项目,主要包含注册和登录的功能。
目录结构如下:
. ├── endpoint # 接收请求,构建 endpoint.Endpoint 调用 service 层的接口方法,处理请求参数,返回响应结果给 transport 层 │ └── user.go ├── go.mod ├── go.sum ├── main.go ├── service # 定义业务接口并实现接口方法 │ └── user.go └── transport # 对外提供调用接口(http 或 rpc) └── http.go
- service 包定义服务(user 服务)的接口,并实现接口方法。
... type IUser interface { Register(ctx context.Context, req *RegisterRequest) (*User, error) Login(ctx context.Context, email, password string) (*User, error) } ...
- endpoint 包为接口方法构建 endpoint.Endpoint,将请求参数转换为接口方法可以处理的参数,并将返回的响应结果封装为对应的 response 结构体,返回给 transport 包。
... type RegisterRequest struct { UserName string Email string Password string } type RegisterResponse struct { User *service.User } func MakeRegisterEndpoint(iUser service.IUser) endpoint.Endpoint { return func(ctx context.Context, request interface{}) (response interface{}, err error) { req := request.(*RegisterRequest) user, err := iUser.Register(ctx, &service.RegisterRequest{ UserName: req.UserName, Email: req.Email, Password: req.Password, }) return &RegisterResponse{User: user}, err } } ...
- transport 包把构建的 endpoint.Endpoint 提供给调用方。
... func NewHttpHandler(ctx context.Context, endpoints *endpoint.Endpoints) http.Handler { r := http.NewServeMux() r.Handle("/register", kitHttp.NewServer(endpoints.RegisterEndpoint, decRegisterRequest, encResponse)) return r } ...
- 在 main 函数中,创建 service、endpoint 和 transport,并启动 Web 服务器。
func main() { ctx := context.Background() userService := service.NewUserService() endpoints := &endpoint.Endpoints{ RegisterEndpoint: endpoint.MakeRegisterEndpoint(userService), LoginEndpoint: endpoint.MakeLoginEndpoint(userService), } r := transport.NewHttpHandler(ctx, endpoints) err := http.ListenAndServe(":8080", r) if err != nil { log.Fatal(err) return } }
- 使用 go run 命令启动,并使用 cURL 调用 http 接口。
go run main.go curl -X POST http://localhost:8080/register \ -d 'email=gopher@88.com&password=123456&username=gopher'
完整代码,请参阅 Github。
03
总结
本文我们通过一个简单的用户中心项目,介绍如何基于 Go kit 开发 Web 项目,为了方便读者朋友们理解代码,项目代码中未使用其他组件,感兴趣的读者朋友可以尝试完善,例如添加操作数据库的代码。
推荐阅读:
参考资料:
https://github.com/go-kit/examples/tree/master/apigateway