You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

3.9 KiB

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

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

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

https://example.com/v1/users https://example.com/v2/users 在上文路由中,我们通过版本 v1 和 v2 来区分了 /users 路由,我们可以通过 api 语言来声明路由前缀:

syntax = "v1"

type UserV1 { Name string json:"name" }

type UserV2 { Name string json:"name" }

@server ( prefix: /v1 ) service user-api { @handler usersv1 get /users returns ([]UserV1) }

@server ( prefix: /v2 ) service user-api { @handler usersv2 get /users returns ([]UserV2) }

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

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

func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { server.AddRoutes( []rest.Route{ { Method: http.MethodGet, Path: "/users", Handler: usersv1Handler(serverCtx), }, }, rest.WithPrefix("/v1"), )

server.AddRoutes(
    []rest.Route{
        {
            Method:  http.MethodGet,
            Path:    "/users",
            Handler: usersv2Handler(serverCtx),
        },
    },
    rest.WithPrefix("/v2"),
)

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

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

在 api 描述语言中,有特定的路由规则,这些路由规则并非和 HTTP 的路由规则完全引用,接下来我们来看一下 api 描述语言中的路由规则吧。

路由规则 ​ 在 api 描述语言中,路由需要满足如下规则

路由必须以 / 开头 路由节点必须以 / 分隔 路由节点中可以包含 :,但是 : 必须是路由节点的第一个字符,: 后面的节点值必须要在结请求体中有 path tag 声明,用于接收路由参数,详细规则可参考 路由参数。 路由节点可以包含字母、数字(goctl 1.5.1 支持,可参考 新版 API 解析器使用)、下划线、中划线 路由示例:

syntax = "v1"

type DemoPath3Req { Id int64 path:"id" }

type DemoPath4Req { Id int64 path:"id" Name string path:"name" }

type DemoPath5Req { Id int64 path:"id" Name string path:"name" Age int path:"age" }

type DemoReq {}

type DemoResp {}

service Demo { // 示例路由 /foo @handler demoPath1 get /foo (DemoReq) returns (DemoResp)

// 示例路由 /foo/bar
@handler demoPath2
get /foo/bar (DemoReq) returns (DemoResp)

// 示例路由 /foo/bar/:id,其中 id 为请求体中的字段
@handler demoPath3
get /foo/bar/:id (DemoPath3Req) returns (DemoResp)

// 示例路由 /foo/bar/:id/:name,其中 id,name 为请求体中的字段
@handler demoPath4
get /foo/bar/:id/:name (DemoPath4Req) returns (DemoResp)

// 示例路由 /foo/bar/:id/:name/:age,其中 id,name,age 为请求体中的字段
@handler demoPath5
get /foo/bar/:id/:name/:age (DemoPath5Req) returns (DemoResp)

// 示例路由 /foo/bar/baz-qux
@handler demoPath6
get /foo/bar/baz-qux (DemoReq) returns (DemoResp)

// 示例路由 /foo/bar_baz/123(goctl 1.5.1 支持)
@handler demoPath7
get /foo/bar_baz/123 (DemoReq) returns (DemoResp)

}