Service Group

Overview

In go-zero, we declared HTTP service via api language, and then generated HTTP service code via goctl, after our systematic introduction to API norm.

In HTTP service development, as business develops, our services interfaces will grow, and the number of code files generated (handler, logic files, etc.) will grow, when some of the generated code files will need to be aggregated in order to facilitate development and maintenance.

Service Group

Assume that we have a user service, we have multiple interfaces below:

  1. https://example.com/v1/user/login
  2. https://example.com/v1/user/info
  3. https://example.com/v1/user/info/update
  4. https://example.com/v1/user/list
  5. https://example.com/v1/user/role/list
  6. https://example.com/v1/user/role/update
  7. https://example.com/v1/user/role/info
  8. https://example.com/v1/user/role/add
  9. https://example.com/v1/user/role/delete
  10. https://example.com/v1/user/class/list
  11. https://example.com/v1/user/class/update
  12. https://example.com/v1/user/class/info
  13. https://example.com/v1/user/class/add
  14. https://example.com/v1/user/class/delete

Let’s first look at api language prophylactic without grouping:

  1. syntax = "v1"
  2. type (
  3. UserLoginReq{}
  4. UserInfoReq{}
  5. UserLoginResp{}
  6. UserInfoResp{}
  7. UserInfoUpdateReq{}
  8. UserInfoUpdateResp{}
  9. )
  10. type (
  11. UserRoleReq{}
  12. UserRoleResp{}
  13. UserRoleUpdateReq{}
  14. UserRoleUpdateResp{}
  15. UserRoleAddReq{}
  16. UserRoleAddResp{}
  17. UserRoleDeleteReq{}
  18. UserRoleDeleteResp{}
  19. )
  20. type (
  21. UserClassReq{}
  22. UserClassResp{}
  23. UserClassUpdateReq{}
  24. UserClassUpdateResp{}
  25. UserClassAddReq{}
  26. UserClassAddResp{}
  27. UserClassDeleteReq{}
  28. UserClassDeleteResp{}
  29. )
  30. @server(
  31. prefix: /v1
  32. )
  33. service user-api {
  34. @handler UserLogin
  35. post /user/login (UserLoginReq) returns (UserLoginResp)
  36. @handler UserInfo
  37. post /user/info (UserInfoReq) returns (UserInfoResp)
  38. @handler UserInfoUpdate
  39. post /user/info/update (UserInfoUpdateReq) returns (UserInfoUpdateResp)
  40. @handler UserList
  41. get /user/list returns ([]UserInfoResp)
  42. @handler UserRoleList
  43. get /user/role/list returns ([]UserRoleResp)
  44. @handler UserRoleUpdate
  45. get /user/role/update (UserRoleUpdateReq) returns (UserRoleUpdateResp)
  46. @handler UserRoleInfo
  47. get /user/role/info (UserRoleReq) returns (UserRoleResp)
  48. @handler UserRoleAdd
  49. get /user/role/add (UserRoleAddReq) returns (UserRoleAddResp)
  50. @handler UserRoleDelete
  51. get /user/role/delete (UserRoleDeleteReq) returns (UserRoleDeleteResp)
  52. @handler UserClassList
  53. get /user/class/list returns ([]UserClassResp)
  54. @handler UserClassUpdate
  55. get /user/class/update (UserClassUpdateReq) returns (UserClassUpdateResp)
  56. @handler UserClassInfo
  57. get /user/class/info (UserClassReq) returns (UserClassResp)
  58. @handler UserClassAdd
  59. get /user/class/add (UserClassAddReq) returns (UserClassAddResp)
  60. @handler UserClassDelete
  61. get /user/class/delete (UserClassDeleteReq) returns (UserClassDeleteResp)
  62. }

Code directory structure generated without a group below:

  1. .
  2. ├── etc
  3. └── user-api.yaml
  4. ├── internal
  5. ├── config
  6. └── config.go
  7. ├── handler
  8. ├── routes.go
  9. ├── userclassaddhandler.go
  10. ├── userclassdeletehandler.go
  11. ├── userclassinfohandler.go
  12. ├── userclasslisthandler.go
  13. ├── userclassupdatehandler.go
  14. ├── userinfohandler.go
  15. ├── userinfoupdatehandler.go
  16. ├── userlisthandler.go
  17. ├── userloginhandler.go
  18. ├── userroleaddhandler.go
  19. ├── userroledeletehandler.go
  20. ├── userroleinfohandler.go
  21. ├── userrolelisthandler.go
  22. └── userroleupdatehandler.go
  23. ├── logic
  24. ├── userclassaddlogic.go
  25. ├── userclassdeletelogic.go
  26. ├── userclassinfologic.go
  27. ├── serclasslistlogic.go
  28. ├── userclassupdatelogic.go
  29. ├── userinfologic.go
  30. ├── userinfoupdatelogic.go
  31. ├── userlistlogic.go
  32. ├── userloginlogic.go
  33. ├── userroleaddlogic.go
  34. ├── userroledeletelogic.go
  35. ├── userroleinfologic.go
  36. ├── userrolelistlogic.go
  37. └── userroleupdatelogic.go
  38. ├── svc
  39. └── servicecontext.go
  40. └── types
  41. └── types.go
  42. ├── user.api
  43. └── user.go
  44. 7 directories, 35 files

Since we do not group in groups, all the files in the generated code handler and the log directory are blown together. This directory structure is not well managed and read in the project, and we follow as user,role,class for grouping. In api language, we can group by using server group keywords in the group groups below:

  1. syntax = "v1"
  2. type (
  3. UserLoginReq {}
  4. UserInfoReq {}
  5. UserLoginResp {}
  6. UserInfoResp {}
  7. UserInfoUpdateReq {}
  8. UserInfoUpdateResp {}
  9. )
  10. type (
  11. UserRoleReq {}
  12. UserRoleResp {}
  13. UserRoleUpdateReq {}
  14. UserRoleUpdateResp {}
  15. UserRoleAddReq {}
  16. UserRoleAddResp {}
  17. UserRoleDeleteReq {}
  18. UserRoleDeleteResp {}
  19. )
  20. type (
  21. UserClassReq {}
  22. UserClassResp {}
  23. UserClassUpdateReq {}
  24. UserClassUpdateResp {}
  25. UserClassAddReq {}
  26. UserClassAddResp {}
  27. UserClassDeleteReq {}
  28. UserClassDeleteResp {}
  29. )
  30. @server (
  31. prefix: /v1
  32. group: user
  33. )
  34. service user-api {
  35. @handler UserLogin
  36. post /user/login (UserLoginReq) returns (UserLoginResp)
  37. @handler UserInfo
  38. post /user/info (UserInfoReq) returns (UserInfoResp)
  39. @handler UserInfoUpdate
  40. post /user/info/update (UserInfoUpdateReq) returns (UserInfoUpdateResp)
  41. @handler UserList
  42. get /user/list returns ([]UserInfoResp)
  43. }
  44. @server (
  45. prefix: /v1
  46. group: role
  47. )
  48. service user-api {
  49. @handler UserRoleList
  50. get /user/role/list returns ([]UserRoleResp)
  51. @handler UserRoleUpdate
  52. get /user/role/update (UserRoleUpdateReq) returns (UserRoleUpdateResp)
  53. @handler UserRoleInfo
  54. get /user/role/info (UserRoleReq) returns (UserRoleResp)
  55. @handler UserRoleAdd
  56. get /user/role/add (UserRoleAddReq) returns (UserRoleAddResp)
  57. @handler UserRoleDelete
  58. get /user/role/delete (UserRoleDeleteReq) returns (UserRoleDeleteResp)
  59. }
  60. @server (
  61. prefix: /v1
  62. group: class
  63. )
  64. service user-api {
  65. @handler UserClassList
  66. get /user/class/list returns ([]UserClassResp)
  67. @handler UserClassUpdate
  68. get /user/class/update (UserClassUpdateReq) returns (UserClassUpdateResp)
  69. @handler UserClassInfo
  70. get /user/class/info (UserClassReq) returns (UserClassResp)
  71. @handler UserClassAdd
  72. get /user/class/add (UserClassAddReq) returns (UserClassAddResp)
  73. @handler UserClassDelete
  74. get /user/class/delete (UserClassDeleteReq) returns (UserClassDeleteResp)
  75. }

Let’s look again at the code-generation directory structure after grouping:

  1. .
  2. ├── etc
  3. └── user-api.yaml
  4. ├── internal
  5. ├── config
  6. └── config.go
  7. ├── handler
  8. ├── class
  9. ├── userclassaddhandler.go
  10. ├── userclassdeletehandler.go
  11. ├── userclassinfohandler.go
  12. ├── userclasslisthandler.go
  13. └── userclassupdatehandler.go
  14. ├── role
  15. ├── userroleaddhandler.go
  16. ├── userroledeletehandler.go
  17. ├── userroleinfohandler.go
  18. ├── userrolelisthandler.go
  19. └── userroleupdatehandler.go
  20. ├── routes.go
  21. └── user
  22. ├── userinfohandler.go
  23. ├── userinfoupdatehandler.go
  24. ├── userlisthandler.go
  25. └── userloginhandler.go
  26. ├── logic
  27. ├── class
  28. ├── userclassaddlogic.go
  29. ├── userclassdeletelogic.go
  30. ├── userclassinfologic.go
  31. ├── userclassupdatelogic.go
  32. └── usersclaslistlogic.go
  33. ├── role
  34. ├── userroleaddlogic.go
  35. ├── userroledeletelogic.go
  36. ├── userroleinfologic.go
  37. ├── userrolelistlogic.go
  38. └── userroleupdatelogic.go
  39. └── user
  40. ├── userinfologic.go
  41. ├── userinfoupdatelogic.go
  42. ├── userlistlogic.go
  43. └── userloginlogic.go
  44. ├── svc
  45. └── servicecontext.go
  46. └── types
  47. └── types.go
  48. ├── user.api
  49. └── user.go
  50. 13 directories, 35 files

By clustering we can easily group different business logic into different directories so that different business logic can be managed easily.