我最初的用例:
我正在使用gRPC
服务器构建一个GO应用程序(使用protobuf
),并将其封装在HTTPS服务器中(使用gin
)。只有HTTPS服务器被发布到客户端以供使用(我的意思是,我的应用程序可以通过REST访问,然后在gRPC端点上拨号),并且我使用Swagger
OpenAPI3 (这里的主要要求是第3版)发布它。gRPC和HTTPS都是必需的,任何解决方案都应该遵循这个体系结构。
我不想在两个地方维护我的服务器规范,也就是说,我不想同时维护proto文件(.proto
)和swagger规范(.json/.yaml
)。由于我绝对需要编写proto文件来生成gRPC服务器,所以我想要自动生成swagger规范(OpenAPI3)。
我所处的位置:
我能够使用swagger
库(如:grpc-rest-示例 )从protobuf文件(.proto
)生成.proto
规范。但是我的需求是OpenAPI3;更具体地说,我想在OpenAPI3中使用oneOf
特性,并从proto的oneof
特性映射到它。这在OpenAPI2中是不可能的,因为它不允许API具有多类型定义的请求/响应主体,这是通过启用oneOf、anyOf和allOf构造在OpenAPI3中添加的特性。
在尝试这样做时,我偶然发现了GoogleAPI 谷歌跳跃/诺斯替者的这个库,其描述如下:
这个存储库包含一个Go命令行工具,该工具可以将JSON和YAML OpenAPI描述转换成等效的协议缓冲区表示。
乍看之下,这似乎完全解决了我的问题,但事实证明,这个库只在协议缓冲区(protobuf)二进制(.pb
)和swagger OpenAPI3 2/OpenAPI3 3 (.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
可能无法正确查看,请访问它这里。所以,就像:
�status��
��string
看上去:
<0x06>status<0x12><0x0b>
Ê<0x01><0x06>string
例如,对于上面的示例,我首先编写了swagger规范,然后生成了.pb
,但同样的方法可以反过来进行。
现状:
如果i有一种在(.pb
)和(.proto
)文件之间进行转换的方法,则转换循环将关闭并完成(.proto
-> .pb
-> .json/.yaml
-> .pb
-> .proto
)。
我相信一定要有办法才能做到这一点,所以我原来的问题是有办法解决的。但我找不到任何文章或代码来做这件事。是否有合理的方法在.pb
和.proto
文件之间进行相互转换?
如果您有一个完全不同的解决方案,我的原始用例,请随时分享,以及。会有很大帮助的。
提前感谢!
编辑:
(1)由于最近的评论,很明显,.pb
和.proto
之间的“转换”首先是一个荒谬的要求。但最初的问题仍然是一样的,即如何使用注释、标记或其他方式从protobuf (.proto
)生成OpenAPI3 (OpenAPI3)规范。相应地更改问题标题。
(2)就在第二天,我发布了这篇文章,我偶然进入了诺斯替-grpc存储库,其中描述说:
该工具将OpenAPI v3.0API描述转换为gRPC服务的描述,该描述可用于使用实现该API。
又一次,这让我太早就离开了。实际上,这是一个GSOC项目,尽管这个存储库的想法很棒,但它并没有实现要求。此外,这不是一个互转换库,对于任何生产用途来说都是非常不成熟的。实际上,它未能提供OpenAPI3规范的一些基本特性。
但是这个存储库正朝着正确的方向发展。我的结论是有一个定制插件来实现这一点,主要是通过扩展GO中的注释库来实现的。
(3)从.proto
转换到OpenAPI3规范(.yaml/.json
)显然没有很好的、明显的选择,除了诺斯替-grpc是非常不成熟的,在任何实际应用中都有很高的工作进度。
但是对于反向转换,即OpenAPI3规范(.yaml/.json
)到.proto
,有一个很好的库,称为OpenAPITools下的开式发电机,它将几乎所有平台的OpenAPI v2/3规范转换为客户机/服务器存根。但是,由于这不是最初的问题,所以问题仍然没有解决。
发布于 2020-04-29 08:12:39
尽管您的要求似乎是从PROTO中获取YAML (OpenAPNv3)规范,但是您可以签出这个插件-- 诺斯替-grpc --用于进行反向转换,即从YAML/JSON规范到proto的转换以及gRPC服务调用。
发布于 2022-07-26 03:05:46
我们未能找到将.proto
文件转换为OpenAPI3 3/Swagger3 3的直接方法。这里有一个解决办法
.proto
将Swagger2文件转换为protoc-gen-openapiv2
示例
protoc --proto_path=${PROTO_PATH} --swagger_out=logtostderr=true:./swagger.json
swagger-codegen generate -i ./swagger.json -l openapi-yaml -o swaggerv3.yaml
https://stackoverflow.com/questions/61350097
复制相似问题