服务分组

概述

go-zero 采用 gRPC 进行服务间的通信,我们通过 proto 文件来定义服务的接口,但是在实际的开发中,我们可能会有多个服务,如果不对服务进行文件分组,那么 goctl 生成的代码将会是一个大的文件夹,这样会导致代码的可维护性变差,因此服务分组可以提高代码的可读性和可维护性。

服务分组

在 go-zero 中,我们通过在 proto 文件中以 service 为维度来进行文件分组,我们可以在 proto 文件中定义多个 service,每个 service 都会生成一个独立的文件夹,这样就可以将不同的服务进行分组,从而提高代码的可读性和可维护性。

除了 proto 文件中定义了 service 外,分组与否还需要在 goctl 中控制,生成带分组或者不带分组的代码取决于开发者,我们通过示例来演示一下。

不带分组

假设我们有一个 proto 文件,如下:

  1. syntax = "proto3";
  2. package user;
  3. option go_package = "github.com/example/user";
  4. message LoginReq{}
  5. message LoginResp{}
  6. message UserInfoReq{}
  7. message UserInfoResp{}
  8. message UserInfoUpdateReq{}
  9. message UserInfoUpdateResp{}
  10. message UserListReq{}
  11. message UserListResp{}
  12. message UserRoleListReq{}
  13. message UserRoleListResp{}
  14. message UserRoleUpdateReq{}
  15. message UserRoleUpdateResp{}
  16. message UserRoleInfoReq{}
  17. message UserRoleInfoResp{}
  18. message UserRoleAddReq{}
  19. message UserRoleAddResp{}
  20. message UserRoleDeleteReq{}
  21. message UserRoleDeleteResp{}
  22. message UserClassListReq{}
  23. message UserClassListResp{}
  24. message UserClassUpdateReq{}
  25. message UserClassUpdateResp{}
  26. message UserClassInfoReq{}
  27. message UserClassInfoResp{}
  28. message UserClassAddReq{}
  29. message UserClassAddResp{}
  30. message UserClassDeleteReq{}
  31. message UserClassDeleteResp{}
  32. service UserService{
  33. rpc Login (LoginReq) returns (LoginResp);
  34. rpc UserInfo (UserInfoReq) returns (UserInfoResp);
  35. rpc UserInfoUpdate (UserInfoUpdateReq) returns (UserInfoUpdateResp);
  36. rpc UserList (UserListReq) returns (UserListResp);
  37. rpc UserRoleList (UserRoleListReq) returns (UserRoleListResp);
  38. rpc UserRoleUpdate (UserRoleUpdateReq) returns (UserRoleUpdateResp);
  39. rpc UserRoleInfo (UserRoleInfoReq) returns (UserRoleInfoResp);
  40. rpc UserRoleAdd (UserRoleAddReq) returns (UserRoleAddResp);
  41. rpc UserRoleDelete (UserRoleDeleteReq) returns (UserRoleDeleteResp);
  42. rpc UserClassList (UserClassListReq) returns (UserClassListResp);
  43. rpc UserClassUpdate (UserClassUpdateReq) returns (UserClassUpdateResp);
  44. rpc UserClassInfo (UserClassInfoReq) returns (UserClassInfoResp);
  45. rpc UserClassAdd (UserClassAddReq) returns (UserClassAddResp);
  46. rpc UserClassDelete (UserClassDeleteReq) returns (UserClassDeleteResp);
  47. }

我们来看一下不分组的情况下,goctl 生成的代码结构:

  1. $ goctl rpc protoc user.proto --go_out=. --go-grpc_out=. --zrpc_out=.
  2. $ tree
  3. .
  4. ├── etc
  5. └── user.yaml
  6. ├── github.com
  7. └── example
  8. └── user
  9. ├── user.pb.go
  10. └── user_grpc.pb.go
  11. ├── go.mod
  12. ├── internal
  13. ├── config
  14. └── config.go
  15. ├── logic
  16. ├── loginlogic.go
  17. ├── userclassaddlogic.go
  18. ├── userclassdeletelogic.go
  19. ├── userclassinfologic.go
  20. ├── userclasslistlogic.go
  21. ├── userclassupdatelogic.go
  22. ├── userinfologic.go
  23. ├── userinfoupdatelogic.go
  24. ├── userlistlogic.go
  25. ├── userroleaddlogic.go
  26. ├── userroledeletelogic.go
  27. ├── userroleinfologic.go
  28. ├── userrolelistlogic.go
  29. └── userroleupdatelogic.go
  30. ├── server
  31. └── userserviceserver.go
  32. └── svc
  33. └── servicecontext.go
  34. ├── user.go
  35. ├── user.proto
  36. └── userservice
  37. └── userservice.go
  38. 10 directories, 24 files
服务分组 - 图1温馨提示

在不进行分组的情况下,不支持在 proto 文件中定义多个 service,否则会报错。

带分组

首先,我们需要在 proto 文件中定义多个 service,如下:

  1. syntax = "proto3";
  2. package user;
  3. option go_package = "github.com/example/user";
  4. message LoginReq{}
  5. message LoginResp{}
  6. message UserInfoReq{}
  7. message UserInfoResp{}
  8. message UserInfoUpdateReq{}
  9. message UserInfoUpdateResp{}
  10. message UserListReq{}
  11. message UserListResp{}
  12. service UserService{
  13. rpc Login (LoginReq) returns (LoginResp);
  14. rpc UserInfo (UserInfoReq) returns (UserInfoResp);
  15. rpc UserInfoUpdate (UserInfoUpdateReq) returns (UserInfoUpdateResp);
  16. rpc UserList (UserListReq) returns (UserListResp);
  17. }
  18. message UserRoleListReq{}
  19. message UserRoleListResp{}
  20. message UserRoleUpdateReq{}
  21. message UserRoleUpdateResp{}
  22. message UserRoleInfoReq{}
  23. message UserRoleInfoResp{}
  24. message UserRoleAddReq{}
  25. message UserRoleAddResp{}
  26. message UserRoleDeleteReq{}
  27. message UserRoleDeleteResp{}
  28. service UserRoleService{
  29. rpc UserRoleList (UserRoleListReq) returns (UserRoleListResp);
  30. rpc UserRoleUpdate (UserRoleUpdateReq) returns (UserRoleUpdateResp);
  31. rpc UserRoleInfo (UserRoleInfoReq) returns (UserRoleInfoResp);
  32. rpc UserRoleAdd (UserRoleAddReq) returns (UserRoleAddResp);
  33. rpc UserRoleDelete (UserRoleDeleteReq) returns (UserRoleDeleteResp);
  34. }
  35. message UserClassListReq{}
  36. message UserClassListResp{}
  37. message UserClassUpdateReq{}
  38. message UserClassUpdateResp{}
  39. message UserClassInfoReq{}
  40. message UserClassInfoResp{}
  41. message UserClassAddReq{}
  42. message UserClassAddResp{}
  43. message UserClassDeleteReq{}
  44. message UserClassDeleteResp{}
  45. service UserClassService{
  46. rpc UserClassList (UserClassListReq) returns (UserClassListResp);
  47. rpc UserClassUpdate (UserClassUpdateReq) returns (UserClassUpdateResp);
  48. rpc UserClassInfo (UserClassInfoReq) returns (UserClassInfoResp);
  49. rpc UserClassAdd (UserClassAddReq) returns (UserClassAddResp);
  50. rpc UserClassDelete (UserClassDeleteReq) returns (UserClassDeleteResp);
  51. }

我们来看一下带分组的情况下,goctl 生成的代码结构:

  1. # 通过 -m 指定 goctl 生成分组的代码
  2. $ goctl rpc protoc user.proto --go_out=. --go-grpc_out=. --zrpc_out=. -m
  3. $ tree
  4. .
  5. ├── client
  6. ├── userclassservice
  7. └── userclassservice.go
  8. ├── userroleservice
  9. └── userroleservice.go
  10. └── userservice
  11. └── userservice.go
  12. ├── etc
  13. └── user.yaml
  14. ├── github.com
  15. └── example
  16. └── user
  17. ├── user.pb.go
  18. └── user_grpc.pb.go
  19. ├── go.mod
  20. ├── internal
  21. ├── config
  22. └── config.go
  23. ├── logic
  24. ├── userclassservice
  25. ├── userclassaddlogic.go
  26. ├── userclassdeletelogic.go
  27. ├── userclassinfologic.go
  28. ├── userclasslistlogic.go
  29. └── userclassupdatelogic.go
  30. ├── userroleservice
  31. ├── userroleaddlogic.go
  32. ├── userroledeletelogic.go
  33. ├── userroleinfologic.go
  34. ├── userrolelistlogic.go
  35. └── userroleupdatelogic.go
  36. └── userservice
  37. ├── loginlogic.go
  38. ├── userinfologic.go
  39. ├── userinfoupdatelogic.go
  40. └── userlistlogic.go
  41. ├── server
  42. ├── userclassservice
  43. └── userclassserviceserver.go
  44. ├── userroleservice
  45. └── userroleserviceserver.go
  46. └── userservice
  47. └── userserviceserver.go
  48. └── svc
  49. └── servicecontext.go
  50. ├── user.go
  51. └── user.proto
  52. 19 directories, 28 files

通过目录结构我们可以看出,logic、server、client 目录都会根据 service 进行分组。