kratos安装
go install github.com/go-kratos/kratos/cmd/kratos/v2@latest
创建项目
安装完毕后直接使用kratos new命令直接创建项目
kratos new project_name
最终创建项目目录如下:
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── api
│ └── helloworld
│ └── v1
│ ├── error_reason.pb.go
│ ├── error_reason.proto
│ ├── greeter.pb.go
│ ├── greeter.proto
│ ├── greeter_grpc.pb.go
│ └── greeter_http.pb.go
├── cmd
│ └── helloworld
│ ├── main.go
│ ├── wire.go
│ └── wire_gen.go
├── configs
│ └── config.yaml
├── go.mod
├── go.sum
├── internal
│ ├── biz
│ │ ├── README.md
│ │ ├── biz.go
│ │ └── greeter.go
│ ├── conf
│ │ ├── conf.pb.go
│ │ └── conf.proto
│ ├── data
│ │ ├── README.md
│ │ ├── data.go
│ │ └── greeter.go
│ ├── server
│ │ ├── grpc.go
│ │ ├── http.go
│ │ └── server.go
│ └── service
│ ├── README.md
│ ├── greeter.go
│ └── service.go
├── openapi.yaml
└── third_party
├── README.md
├── errors
│ └── errors.proto
├── google
│ ├── api
│ │ ├── annotations.proto
│ │ ├── client.proto
│ │ ├── field_behavior.proto
│ │ ├── http.proto
│ │ └── httpbody.proto
│ └── protobuf
│ ├── any.proto
│ ├── api.proto
│ ├── compiler
│ │ └── plugin.proto
│ ├── descriptor.proto
│ ├── duration.proto
│ ├── empty.proto
│ ├── field_mask.proto
│ ├── source_context.proto
│ ├── struct.proto
│ ├── timestamp.proto
│ ├── type.proto
│ └── wrappers.proto
├── openapi
│ └── v3
│ ├── annotations.proto
│ └── openapi.proto
└── validate
├── README.md
└── validate.proto
- api:接口定义的proto文件在这个目录下面
- cmd:程序入口
- internal:业务逻辑
- third_party:第三方依赖
基础开发流程
proto文件编写
kratos proto add api/helloworld/v1/greeter.proto
上述命令会直接生成crud四个基础接口定义,按照需求往里面编写我们需要的接口,基础接口定义如下:
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {
option (google.api.http) = {
get: "/helloworld/{name}"
};
}
}
代码生成
生成proto代码
kratos proto client api/helloworld/v1/greeter.proto
生成service代码
kratos proto server api/helloworld/v1/greeter.proto -t internal/service
service和sever注册
在service包service.go中注册service
var ProviderSet = wire.NewSet(NewGreeterService)
在server中注册,分别在server包的http.go和grpc.go文件中
v1.RegisterGreeterHTTPServer(srv, greeter)
调用链路
service调用biz层,biz层调用data层,data层才是最终操作数据库的地方
biz层代码
type Greeter struct {
Hello string
}
// GreeterRepo is a Greater repo.
type GreeterRepo interface {
Save(context.Context, *Greeter) (*Greeter, error)
Update(context.Context, *Greeter) (*Greeter, error)
FindByID(context.Context, int64) (*Greeter, error)
ListByHello(context.Context, string) ([]*Greeter, error)
ListAll(context.Context) ([]*Greeter, error)
}
// GreeterUsecase is a Greeter usecase.
type GreeterUsecase struct {
repo GreeterRepo
log *log.Helper
}
定义一个struct实体对应请求响应以及struct_repo的接口,struct_repo_usecase会基层repo以及log,最后在biz中注册var ProviderSet = wire.NewSet(NewGreeterUsecase)
data层代码
var ProviderSet = wire.NewSet(NewData, NewGreeterRepo)
// Data .
type Data struct {
// TODO wrapped database client
}
// NewData .
func NewData(c *conf.Data, logger log.Logger) (*Data, func(), error) {
cleanup := func() {
log.NewHelper(logger).Info("closing the data resources")
}
return &Data{}, cleanup, nil
}
data.go这里会集成数据库实例
type greeterRepo struct {
data *Data
log *log.Helper
}
// NewGreeterRepo .
func NewGreeterRepo(data *Data, logger log.Logger) biz.GreeterRepo {
return &greeterRepo{
data: data,
log: log.NewHelper(logger),
}
}
func (r *greeterRepo) Save(ctx context.Context, g *biz.Greeter) (*biz.Greeter, error) {
return g, nil
}
func (r *greeterRepo) Update(ctx context.Context, g *biz.Greeter) (*biz.Greeter, error) {
return g, nil
}
func (r *greeterRepo) FindByID(context.Context, int64) (*biz.Greeter, error) {
return nil, nil
}
func (r *greeterRepo) ListByHello(context.Context, string) ([]*biz.Greeter, error) {
return nil, nil
}
func (r *greeterRepo) ListAll(context.Context) ([]*biz.Greeter, error) {
return nil, nil
}
最终greeterRepo这个struct会继承data结构体,并且实现biz中定义的接口,在data.go中通过依赖注入var ProviderSet = wire.NewSet(NewData, NewGreeterRepo)
示例代码可见:
https://github.com/go-kratos/examples/tree/main/bloghttps://github.com/go-kratos/beer-shop