服务分组

概述

在 go-zero 中,我们通过 api 语言来声明 HTTP 服务,然后通过 goctl 生成 HTTP 服务代码,在之前我们系统性的介绍了 API 规范

在 HTTP 服务开发中,随着业务的发展,我们的服务接口会越来越多,生成的代码文件(handler,logic 文件等)也会越来越多,这时候我们需要将一些生成的代码文件按照一定维度进行文件夹聚合,以便于开发和维护。

服务分组

假设我们有一个用户服务,我们有多个接口如下:

  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

我们首先来看一下在不进行分组的情况下 api 语言的写法:

  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. }

在不分组的情况下生成的代码目录结构如下:

  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

由于我们没有进行分组,所以生成的代码中handler 和 logic 目录下的文件是全部揉在一起的,这样的目录结构在项目中不太好管理和阅读,接下来我们按照 userroleclass 来进行分组,在 api 语言中,我们可以通过在 @server 语句块中使用 group 关键字来进行分组,分组的语法如下:

  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. }

我们再来看一下分组后的代码生成目录结构:

  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

通过分组,我们可以很方便的将不同的业务逻辑分组到不同的目录下,这样可以很方便的管理不同的业务逻辑。