Kratos 集成 Gin
- 规范项目分层
- 处理请求处理、响应
- 编写路由route
- Kratos 集成gin
- 注入 wire set中
源码
Kratos 可以在
.proto
文件定义请求类型,URL,响应等等,如官方示例:
service BlogService {rpc CreateArticle (CreateArticleRequest) returns (CreateArticleReply) {option (google.api.http) = {post: "/v1/article/"body: "*"};}rpc UpdateArticle (UpdateArticleRequest) returns (UpdateArticleReply) {option (google.api.http) = {put: "/v1/article/{id}"body: "*"};}rpc DeleteArticle (DeleteArticleRequest) returns (DeleteArticleReply) {option (google.api.http) = {delete: "/v1/article/{id}"};}rpc GetArticle (GetArticleRequest) returns (GetArticleReply) {option (google.api.http) = {get: "/v1/article/{id}"};}rpc ListArticle (ListArticleRequest) returns (ListArticleReply) {option (google.api.http) = {get: "/v1/article/"};}
}
通过使用命令行工具 kratos 可以生成相关 http 请求处理、路由定义等,省略了自己去处理请求、响应等过程。
Kratos 的项目分层借鉴了 DDD 的思想,在官方推荐的 project layout 中,用户接口层(interfaces)的作用体现在了 api 层。
如果我们不使用官方自带的 http 处理方案(通过 .proto
生成样板代码),而是使用 gin 框架的话,需要自己做如下事情:
- 规范项目分层,在
/internal
目录下,新增一个用户接口层/interfaces
(DDD思想) - 通过gin编写自己的请求处理、响应
- 通过gin定义路由
- kratos 集成 gin
- 注入 wire set 中
规范项目分层
PS :kratos 的 biz 层更多是DDD 中 domain + repo接口定义 ,但是官方该层给的后缀却是 XXUseCase,个人感觉不太对啊, 还是自己的知识错了?
在 /internal
目录下新建 /interfaces
目录
之后的处理请求、编写路由、wire Provider 都在该目录下定义,最终结果如图:
处理请求处理、响应
在用户接口层 /interfaces
编写请求处理的方法,写了个最简单的 SayHi
:
// user.go
package interfacesimport ("context""kratos-admin/internal/service""github.com/go-kratos/kratos/v2/log""github.com/gin-gonic/gin"
)type UserUseCase struct {userService *service.UserServicelog *log.Helper
}func NewUserUseCase(us *service.UserService, logger log.Logger) *UserUseCase {return &UserUseCase{userService: us, log: log.NewHelper(logger)}
}func (u *UserUseCase) SayHi(c *gin.Context) {c.JSON(200, gin.H{"msg": "hello world",})
}
编写路由route
// routes.go package interfacesimport ("github.com/gin-gonic/gin"
)func RegisterHTTPServer(us *UserUseCase) *gin.Engine {router := gin.New()rootGrp := router.Group("/api"){userGrp := rootGrp.Group("/user")userGrp.GET("/sayhi", us.Get)}return router
}
Kratos 集成gin
在 /server/http.go
中注册路由:
// server/http.go// NewHTTPServer new a HTTP server.
func NewHTTPServer(c *conf.Server,user *interfaces.UserUseCase, // 新增参数logger log.Logger) *transHttp.Server {var opts = []transHttp.ServerOption{transHttp.Middleware(recovery.Recovery(),tracing.Server(),logging.Server(logger),metrics.Server(),validate.Validator(),),}if c.Http.Network != "" {opts = append(opts, transHttp.Network(c.Http.Network))}if c.Http.Addr != "" {opts = append(opts, transHttp.Address(c.Http.Addr))}if c.Http.Timeout != nil {opts = append(opts, transHttp.Timeout(c.Http.Timeout.AsDuration()))}srv := transHttp.NewServer(opts...)// 调用 interfaces.RegisterHTTPServer 注入到 srv 中srv.HandlePrefix("/", interfaces.RegisterHTTPServer(user))return srv
}
注入 wire set中
1. 编写 ProviderSet
// interfaces.go
package interfacesimport "github.com/google/wire"// ProviderSet is interfaces providers.
var ProviderSet = wire.NewSet(NewUserUseCase)
2. 增加到 wire.go中
// initApp init kratos application.
func initApp(*conf.Server, *conf.Data, log.Logger) (*kratos.App, func(), error) {panic(wire.Build(server.ProviderSet,data.ProviderSet,biz.ProviderSet,service.ProviderSet,interfaces.ProviderSet, // 新增的 interfaces provider setnewApp))
}
3. 执行 wire 命令,生成新的 wire_gen.go 文件
# cd 到 mian.go 所在的目录中
cd cmd/XXXX # 执行 wire
wire
接下来自己启动项目,测试接口 : http://127.0.0.1:8000/api/user/sayhi 即可
亲测可以~