Service Group
Overview
go-zero uses gRPC to communicate between services. We define the interface of the service with proto files, but we may have multiple services in physical development. If the service is not clustered, the goctl generated code will be a large folder, leading to poor maintenance variability, so that the service group can improve the readability and maintenance of the code.
Service Group
In go-zero, by clustering files using service as a dimension in the proto file. We can define multiple services in the proto file and create a separate folder for each service so that different services can be grouped in order to improve readability and maintenance.
In addition to service defined in proto file, groups need to be controlled in goctl, creating code with or without groups depends on developers. We show it by example.
No group
Assume we have a proto file, below:
syntax = "proto3";
package user;
option go_package = "github.com/example/user";
message LoginReq{}
message LoginResp{}
message UserInfoReq{}
message UserInfoResp{}
message UserInfoUpdateReq{}
message UserInfoUpdateResp{}
message UserListReq{}
message UserListResp{}
message UserRoleListReq{}
message UserRoleListResp{}
message UserRoleUpdateReq{}
message UserRoleUpdateResp{}
message UserRoleInfoReq{}
message UserRoleInfoResp{}
message UserRoleAddReq{}
message UserRoleAddResp{}
message UserRoleDeleteReq{}
message UserRoleDeleteResp{}
message UserClassListReq{}
message UserClassListResp{}
message UserClassUpdateReq{}
message UserClassUpdateResp{}
message UserClassInfoReq{}
message UserClassInfoResp{}
message UserClassAddReq{}
message UserClassAddResp{}
message UserClassDeleteReq{}
message UserClassDeleteResp{}
service UserService{
rpc Login (LoginReq) returns (LoginResp);
rpc UserInfo (UserInfoReq) returns (UserInfoResp);
rpc UserInfoUpdate (UserInfoUpdateReq) returns (UserInfoUpdateResp);
rpc UserList (UserListReq) returns (UserListResp);
rpc UserRoleList (UserRoleListReq) returns (UserRoleListResp);
rpc UserRoleUpdate (UserRoleUpdateReq) returns (UserRoleUpdateResp);
rpc UserRoleInfo (UserRoleInfoReq) returns (UserRoleInfoResp);
rpc UserRoleAdd (UserRoleAddReq) returns (UserRoleAddResp);
rpc UserRoleDelete (UserRoleDeleteReq) returns (UserRoleDeleteResp);
rpc UserClassList (UserClassListReq) returns (UserClassListResp);
rpc UserClassUpdate (UserClassUpdateReq) returns (UserClassUpdateResp);
rpc UserClassInfo (UserClassInfoReq) returns (UserClassInfoResp);
rpc UserClassAdd (UserClassAddReq) returns (UserClassAddResp);
rpc UserClassDelete (UserClassDeleteReq) returns (UserClassDeleteResp);
}
Let’s look at the structure of the code generated by goctl without grouping:
$ goctl rpc protoc user.proto --go_out=. --go-grpc_out=. --zrpc_out=.
$ tree
.
├── etc
│ └── user.yaml
├── github.com
│ └── example
│ └── user
│ ├── user.pb.go
│ └── user_grpc.pb.go
├── go.mod
├── internal
│ ├── config
│ │ └── config.go
│ ├── logic
│ │ ├── loginlogic.go
│ │ ├── userclassaddlogic.go
│ │ ├── userclassdeletelogic.go
│ │ ├── userclassinfologic.go
│ │ ├── userclasslistlogic.go
│ │ ├── userclassupdatelogic.go
│ │ ├── userinfologic.go
│ │ ├── userinfoupdatelogic.go
│ │ ├── userlistlogic.go
│ │ ├── userroleaddlogic.go
│ │ ├── userroledeletelogic.go
│ │ ├── userroleinfologic.go
│ │ ├── userrolelistlogic.go
│ │ └── userroleupdatelogic.go
│ ├── server
│ │ └── userserviceserver.go
│ └── svc
│ └── servicecontext.go
├── user.go
├── user.proto
└── userservice
└── userservice.go
10 directories, 24 files
reminding
does not support the definition of multiple services in proto file without being grouped or reporting errors.
Group
First, we need to define multiple services in proto file, as follows::
syntax = "proto3";
package user;
option go_package = "github.com/example/user";
message LoginReq{}
message LoginResp{}
message UserInfoReq{}
message UserInfoResp{}
message UserInfoUpdateReq{}
message UserInfoUpdateResp{}
message UserListReq{}
message UserListResp{}
service UserService{
rpc Login (LoginReq) returns (LoginResp);
rpc UserInfo (UserInfoReq) returns (UserInfoResp);
rpc UserInfoUpdate (UserInfoUpdateReq) returns (UserInfoUpdateResp);
rpc UserList (UserListReq) returns (UserListResp);
}
message UserRoleListReq{}
message UserRoleListResp{}
message UserRoleUpdateReq{}
message UserRoleUpdateResp{}
message UserRoleInfoReq{}
message UserRoleInfoResp{}
message UserRoleAddReq{}
message UserRoleAddResp{}
message UserRoleDeleteReq{}
message UserRoleDeleteResp{}
service UserRoleService{
rpc UserRoleList (UserRoleListReq) returns (UserRoleListResp);
rpc UserRoleUpdate (UserRoleUpdateReq) returns (UserRoleUpdateResp);
rpc UserRoleInfo (UserRoleInfoReq) returns (UserRoleInfoResp);
rpc UserRoleAdd (UserRoleAddReq) returns (UserRoleAddResp);
rpc UserRoleDelete (UserRoleDeleteReq) returns (UserRoleDeleteResp);
}
message UserClassListReq{}
message UserClassListResp{}
message UserClassUpdateReq{}
message UserClassUpdateResp{}
message UserClassInfoReq{}
message UserClassInfoResp{}
message UserClassAddReq{}
message UserClassAddResp{}
message UserClassDeleteReq{}
message UserClassDeleteResp{}
service UserClassService{
rpc UserClassList (UserClassListReq) returns (UserClassListResp);
rpc UserClassUpdate (UserClassUpdateReq) returns (UserClassUpdateResp);
rpc UserClassInfo (UserClassInfoReq) returns (UserClassInfoResp);
rpc UserClassAdd (UserClassAddReq) returns (UserClassAddResp);
rpc UserClassDelete (UserClassDeleteReq) returns (UserClassDeleteResp);
}
Let’s look at the structure of the code generated by goctl with grouping:
# 通过 -m 指定 goctl 生成分组的代码
$ goctl rpc protoc user.proto --go_out=. --go-grpc_out=. --zrpc_out=. -m
$ tree
.
├── client
│ ├── userclassservice
│ │ └── userclassservice.go
│ ├── userroleservice
│ │ └── userroleservice.go
│ └── userservice
│ └── userservice.go
├── etc
│ └── user.yaml
├── github.com
│ └── example
│ └── user
│ ├── user.pb.go
│ └── user_grpc.pb.go
├── go.mod
├── internal
│ ├── config
│ │ └── config.go
│ ├── logic
│ │ ├── userclassservice
│ │ │ ├── userclassaddlogic.go
│ │ │ ├── userclassdeletelogic.go
│ │ │ ├── userclassinfologic.go
│ │ │ ├── userclasslistlogic.go
│ │ │ └── userclassupdatelogic.go
│ │ ├── userroleservice
│ │ │ ├── userroleaddlogic.go
│ │ │ ├── userroledeletelogic.go
│ │ │ ├── userroleinfologic.go
│ │ │ ├── userrolelistlogic.go
│ │ │ └── userroleupdatelogic.go
│ │ └── userservice
│ │ ├── loginlogic.go
│ │ ├── userinfologic.go
│ │ ├── userinfoupdatelogic.go
│ │ └── userlistlogic.go
│ ├── server
│ │ ├── userclassservice
│ │ │ └── userclassserviceserver.go
│ │ ├── userroleservice
│ │ │ └── userroleserviceserver.go
│ │ └── userservice
│ │ └── userserviceserver.go
│ └── svc
│ └── servicecontext.go
├── user.go
└── user.proto
19 directories, 28 files
We can see through the directory structure that logic, server, and customer directories are grouped according to service.