在gRPC

时间:2018-03-01 08:41:00

标签: rest go protocol-buffers grpc

我使用带协议缓冲区的gRPC实现了API服务,然后使用grpc-gateway将其公开为一组REST Web服务。

现在我已经到了必须维护不同版本API的地步,而且我已经卡住了。

在我的proto文件中,我有一个像这样定义的处理程序

rpc MerchantGet (MerchantRequest) returns (MerchantResponse) {
    option (google.api.http) = {
        get: "/v1.1.0/myapi/merchant/{MerchantID}"
    };
}

在我的Go代码中,我当然有一个函数MerchantGetGET /v1.1.0/myapi/merchant/{MerchantID}行动到MerchantGet

现在,让我们说我想为MerchantGet方法添加更多功能并发布新版本。我打算按照Semantic Versioning Specification保持向后兼容性,所以如果我理解正确,这意味着我可以对我的MerchantRequest方法进行基础更改并让它取代旧方法,只要它不需要不同的输入来自第三方(MerchantResponse)或更改发送给第三方(rpc MerchantGet (MerchantRequest) returns (MerchantResponse) { option (google.api.http) = { get: "/v1.6.0/myapi/merchant/{MerchantID}" additional_bindings { get: "/v1.5.0/myapi/merchant/{MerchantID}" } additional_bindings { get: "/v1.4.2/myapi/merchant/{MerchantID}" } additional_bindings { get: "/v1.4.1/myapi/merchant/{MerchantID}" } additional_bindings { get: "/v1.4.0/myapi/merchant/{MerchantID}" } additional_bindings { get: "/v1.3.0/myapi/merchant/{MerchantID}" } additional_bindings { get: "/v1.2.0/myapi/merchant/{MerchantID}" } additional_bindings { get: "/v1.1.0/myapi/merchant/{MerchantID}" } }; } )的响应,而不是在响应结尾添加其他字段。 (如果我在这个假设中错了,请纠正我。)

我的问题是,我如何编写proto处理程序来为不同版本的端点提供方法?想到的一个选项看起来如下:

additional_bindings

但这肯定不是实现这一目标的惯用方法吗?它当然不是很优雅,因为每个新的次要版本或补丁,我都必须将这些with cte (fromid, toid, groupkey, sortkey) as ( select fromid, toid, row_number() over (order by fromid) as groupkey, 1 as sortkey from mytable where toid not in (select fromid from mytable) union all select m.fromid, m.toid, cte.groupkey, cte.sortkey - 1 from mytable m join cte on cte.fromid = m.toid ) select fromid, toid from cte order by groupkey, sortkey; 扩展到我的每个方法(上面我只使用一种方法作为例子)。

1 个答案:

答案 0 :(得分:3)

来自SemVer规范:

  

给定版本号MAJOR.MINOR.PATCH,增加:

     
      
  1. 当您进行不兼容的API更改时的MAJOR版本,
  2.   
  3. 以向后兼容的方式添加功能时的MINOR版本,
  4.   当您进行向后兼容的错误修复时,
  5. PATCH版本。
  6.         

    预发布和构建元数据的附加标签可作为MAJOR.MINOR.PATCH格式的扩展。

与REST端点版本控制相关的唯一版本是MAJOR版本,因为所有MINOR和PATCH更改必须向后兼容。

回答你的问题:
仅使用REST URI中的主要版本号。从REST的角度来看,其余部分是一个实现细节。

所以,您的原型服务将是:

rpc MerchantGet (MerchantRequest) returns (MerchantResponse) {
    option (google.api.http) = {
        get: "/v1/myapi/merchant/{MerchantID}"
    };
}