go-micro api version

go-micro的api版本机制看example的时候感觉很简单,但是实际要是用的时候,还是有好几个点费了不少时间,最终通过扒code弄的差不多了,这里记录下。

go-micro可以提供同时提供http和grpc的访问,如果不是用自定义的EndPoint时,这两种的api版本控制没有区别,下面分别说下这几种情况下的版本控制机制。

grpc

grpc的访问主要是通过protobuf文件生成的对应语言的文件来访问,所以版本控制是通过protobuf中的package定义来控制的,只需要在package的定义中加入版本信息即可,比如:

//v1
package go.micro.api.v1.test;

//v2
package go.micro.api.v2.test;

这里我理解只要package定义不一样,可以区别出具体的服务即可,v1和v2主要是语义上好理解

版本号建议加在api之后,这样可以保持和http访问时的一致(go-micro api gateway可自动转换grpc到http,下边会详细说)

http

go-micro的http访问主要是通过micro的api网关实现的,目前有两种形式:

/[service]/[method]

http的url按照上面的规则解析,动态转化为rpc的访问,以上面的package定义为例

//v1
package go.micro.api.v1.test;
//url v1/test/hello

//v2
package go.micro.api.v2.test;
//url v2/test/hello


// hello func defined

下面还有几个url解析的官方example更明了一点

PathServiceMethod
/foo/bargo.micro.api.fooFoo.Bar
/foo/bar/bazgo.micro.api.fooBar.Baz
/foo/bar/baz/catgo.micro.api.foo.barBaz.Cat

Versioned API URLs can easily be mapped to service names:

PathServiceMethod
/foo/bargo.micro.api.fooFoo.Bar
/v1/foo/bargo.micro.api.v1.fooFoo.Bar
/v1/foo/bar/bazgo.micro.api.v1.fooBar.Baz
/v2/foo/bargo.micro.api.v2.fooFoo.Bar
/v2/foo/bar/bazgo.micro.api.v2.fooBar.Baz

code中的实现逻辑是:

  • 分割url为数组

  • 根据数组的长度来构建service和method

    • 少于等于2,第一个作为service,整体作为method
    // If we've got two or less parts
    // Use first part as service
    // Use all parts as method
    if len(parts) <= 2 {
    	name := parts[0]
    	return name, methodName(parts)
    }
    
    • 等于3,前面2个作为service,后边2个为method

      // Treat /v[0-9]+ as versioning where we have 3 parts
      

    // /v1/foo/bar => service: v1.foo method: Foo.bar
    if len(parts) == 3 && versionRe.Match([]byte(parts[0])) {
    name := strings.Join(parts[:len(parts)-1], “.”)
    r
    ```

    • 大于3,最后两个作为method,其余所有作为service
    // Service is everything minus last two parts
    // Method is the last two parts
    name := strings.Join(parts[:len(parts)-2], ".")
    return name, methodName(parts[len(parts)-2:])
    

EndPoint

endpoint是上面不同的是,因为url是自己定义的,所以上面的方式解析出来的结果是错误的,所以必须在用url比对路由的地址的时候,就成功,否则就会报错

我这边想到的版本就是在设置EndPoint的时候加入版本号(客户端请求会带版本后,为了在比对的时候保持一致来保证成功找到注册的EndPoint),找到endpoint之后的流程就相同了,这里不过多描述。

之后我会在专门写一篇文章,从code追踪下整个url的解析过程,就会清楚为什么需要保证url一致,比对成功

func registerUser(server server.Server) error {
	return pb.RegisterUserHandler(server, new(Handler),
		mApi.WithEndpoint(&mApi.Endpoint{
			// The RPC method
			Name: "User.Register",
			// The HTTP paths. This can be a POSIX regex
			Path: []string{"^v1/user/register$"},
			// The HTTP Methods for this endpoint
			Method: []string{"POST"},
			// The API handler to use
			Handler: rpc.Handler,
        }),
    )
}

这里的版本号需要和protobuf文件中的package定义的一致,否则还是会出现无法找到对应的服务的错误(上边提到了version添加的位置),因为最终在找到注册的Endpoint后,就和grpc一样,还是需要通过protobuf来访问具体的服务的。

其他

这里还有个问题,就是在main中,初始化micro服务的时候,设置的version到目前为止都没有用到,我好奇搜索了下version关键字,有发现client/selector/filter.go中有对应version的使用,看位置应该是client用来过滤服务的,不过没细看,留个坑,之后来填。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值