路由前缀

概述

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

在 HTTP 服务开发中,路由前缀需求是非常常见的,比如我们通过路由来区分版本,或者通过路由来区分不同的服务,这些都是非常常见的需求。

路由前缀

假设我们有一个用户服务,我们需要通过路由来区分不同的版本,我们可以通过 api 语言来声明路由前缀:

  1. https://example.com/v1/users
  2. https://example.com/v2/users

在上文路由中,我们通过版本 v1v2 来区分了 /users 路由,我们可以通过 api 语言来声明路由前缀:

  1. syntax = "v1"
  2. type UserV1 {
  3. Name string `json:"name"`
  4. }
  5. type UserV2 {
  6. Name string `json:"name"`
  7. }
  8. @server (
  9. prefix: /v1
  10. )
  11. service user-api {
  12. @handler usersv1
  13. get /users returns ([]UserV1)
  14. }
  15. @server (
  16. prefix: /v2
  17. )
  18. service user-api {
  19. @handler usersv2
  20. get /users returns ([]UserV2)
  21. }

在上文中,我们通过在 @server 中来通过 prefix 关键字声明了路由前缀,然后通过 @handler 来声明了路由处理函数,这样我们就可以通过路由前缀来区分不同的版本了。

下面简单看一下生成的路由代码:

  1. func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
  2. server.AddRoutes(
  3. []rest.Route{
  4. {
  5. Method: http.MethodGet,
  6. Path: "/users",
  7. Handler: usersv1Handler(serverCtx),
  8. },
  9. },
  10. rest.WithPrefix("/v1"),
  11. )
  12. server.AddRoutes(
  13. []rest.Route{
  14. {
  15. Method: http.MethodGet,
  16. Path: "/users",
  17. Handler: usersv2Handler(serverCtx),
  18. },
  19. },
  20. rest.WithPrefix("/v2"),
  21. )
  22. }

在上文中,我们可以看到,我们声明的 prefix 其实在生成代码后通过 rest.WithPrefix 来声明了路由前缀,这样我们就可以通过路由前缀来区分不同的版本了。