我正在使用gRPC
服务器(使用protobuf
)在GO中构建应用程序,并将其包装在HTTPS服务器中(使用gin
)。仅将HTTPS服务器发布给客户端以供使用(这意味着我可以通过REST API访问我的应用程序,然后实际上是在gRPC端点上拨号),并且我正在使用Swagger
OpenAPI3发布它(版本3是此处的主要要求)规范。 gRPC和HTTPS都是必需的,任何解决方案都应遵循此架构。
我不想在两个地方都维护我的服务器规范,也就是说,我不想同时维护原始文件(.proto
)和大张旗鼓的规范(.json/.yaml
)。由于我绝对必须编写原型文件才能生成gRPC服务器,因此我想自动化标准规格(OpenAPI3)。
我能够使用grpc-gateway之类的grpc-rest-go-example库从protobuf文件(swagger
)生成.proto
OpenAPI2规范。但我的要求是OpenAPI3;更具体地说,我想使用OpenAPI3中的oneOf
功能并通过proto的oneof
功能映射到它。 这对于OpenAPI2是不可能的,因为它不允许API具有多个类型定义的请求/响应主体,而这是OpenAPI3中通过启用oneOf,anyOf和allOf构造而添加的功能。 < / p>
在尝试这样做时,我偶然发现了GoogleAPI googleapis/gnostic对该库的描述,
此存储库包含一个Go命令行工具,该工具可将JSON和YAML OpenAPI描述与等效的协议缓冲区表示形式相互转换。
乍看之下,这似乎完全解决了我的问题,但事实证明,该库仅在协议缓冲区(protobuf)二进制(.pb
)和张扬的OpenAPI2 / OpenAPI3(.json/.yaml
之间进行转换。 )文件,这使我遇到了新问题。
例如下面的.pb
文件:
�3.0.1�…�
�Example service��Example service description*�
�Example contact2=
Apache 2.0�/http://www.apache.org/licenses/LICENSE-2.0.html:�1.0�!
�//localhost:9999/example/api/v1"â�
�
�/exampleResource��"���Example API��Example API description*�example-operation2B
@
example-query��query��example-query description �R�
Ê��stringBÇ��œ�
�200�”�
‘�
�OK�Š�
C
�application/json�/
-�+
)#/components/schemas/common.StatusMessage
C
�application/yaml�/
-�+
)#/components/schemas/common.StatusMessage�¥�
�400���
š�
�Bad Request�Š�
C
�application/json�/
-�+
)#/components/schemas/common.StatusMessage
C
�application/yaml�/
-�+
)#/components/schemas/common.StatusMessage*Y
W
U
�common.StatusMessage�=
;Ê��objectú�/
�
�message��
��string
�
�status��
��string
它会生成以下swagger文件:
openapi: 3.0.1
info:
title: Example service
description: Example service description
contact:
name: Example contact
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
version: "1.0"
servers:
- url: //localhost:9999/example/api/v1
paths:
/exampleResource:
get:
summary: Example API
description: Example API description
operationId: example-operation
parameters:
- name: example-query
in: query
description: example-query description
required: true
schema:
type: string
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/common.StatusMessage'
application/yaml:
schema:
$ref: '#/components/schemas/common.StatusMessage'
400:
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/common.StatusMessage'
application/yaml:
schema:
$ref: '#/components/schemas/common.StatusMessage'
components:
schemas:
common.StatusMessage:
type: object
properties:
message:
type: string
status:
type: string
.pb
可能无法正确查看,请访问here。像这样:
�status��
��string
看起来像:
<0x06>status<0x12><0x0b>
Ê<0x01><0x06>string
对于上面的示例,我首先编写了swagger规范,然后生成了.pb
,但反之亦然。
如果我可以在(.pb
和(.proto
)个文件之间进行转换,则转换循环将关闭并完成(.proto
- > .pb
-> .json/.yaml
-> .pb
-> .proto
)。
我确信必须有一种方法来实现这一目标,因此存在针对我的原始问题的解决方案。但是我找不到能做到这一点的任何文章或一段代码。是否有在.pb
和.proto
文件之间进行互转换的明智方法?
如果您对我的原始用例有完全不同的解决方案,请随时分享。这会很有帮助。
谢谢!
(1)感谢最近的评论,很明显,.pb
和.proto
之间的“转换”首先是荒谬的询问。但是原始问题仍然相同,即如何使用注释,标签或其他方式从protobuf文件(.proto
)中生成swagger3(OpenAPI3)规范。 相应地更改问题标题。
(2)发布后的第二天,我碰到了gnostic-grpc存储库,该存储库的描述为:
此工具将OpenAPI v3.0 API描述转换为gRPC服务的描述,可用于使用gRPC-JSON转码实现该API。
再次,这让我退出得太早了。实际上,这是一个GSOC项目,并且与该存储库的想法一样令人惊讶,它没有实现requirements。而且,这不是一个互转换库,并且对于任何生产用途来说都非常不成熟。实际上,它无法提供OpenAPI3规范的一些基本基本功能。
但是此存储库的方向正确。我的结论是要有一个自定义插件来执行此操作,主要是通过扩展GO中的注释库。
(3)显然,没有从.proto
转换为OpenAPI3规范(.yaml/.json
的良好且显而易见的候选者,除了gnostic-grpc尚不成熟且任何工作都在进行中真正的用途。
但是对于反向转换(例如,将OpenAPI3规范(.yaml/.json
)转换为.proto
,OpenAPITools下有一个名为openapi-generator的好的库,该库将OpenAPI v2 / 3规范转换为客户端/适用于几乎所有平台的服务器存根。但是,由于这不是最初提出的问题,因此问题仍然悬而未决。
答案 0 :(得分:1)
尽管,您的要求似乎是要从PROTO获得YAML(OpenAPNv3)规范,但您可以签出此插件-gnostic-grpc-以确保gnostic的效果,即将YAML / JSON规范转换为proto和gRPC服务调用。