Мой первоначальный вариант использования:
Я создаю приложение в GO с gRPC
сервером (используя protobuf
) и помещаю его в HTTPS-сервер (используя gin
). Для использования клиентам публикуется только HTTPS-сервер (я имею в виду, что к моему приложению можно получить доступ через REST API, который затем набирает номер на конечной точке gRPC), и я публикую его, используя Swagger
OpenAPI3 (версия 3 - это здесь главное требование) спецификация. Требуются и gRPC, и HTTPS, и любое решение должно соответствовать этой архитектуре.
Я не хочу поддерживать спецификацию моего сервера в двух местах, то есть я не хочу поддерживать оба файла proto (.proto
) и спецификацию swagger (.json/.yaml
). Поскольку мне абсолютно необходимо писать прото-файлы для генерации сервера gRPC, я хочу автоматизировать генерацию спецификации swagger (OpenAPI3).
Где я:
Я могу создать swagger
спецификацию OpenAPI2 из файлов protobuf (.proto
), используя библиотеку grpc-gateway примерно так: grpc-rest-go-example. Но мое требование - OpenAPI3; более конкретно, я хочу использовать функцию oneOf
в OpenAPI3 и сопоставить ее с функцией oneof
proto. Это невозможно с OpenAPI2, поскольку он не позволяет API иметь тело запроса / ответа с несколькими определениями типов, что было функцией, добавленной в OpenAPI3 путем включения конструкций oneOf, anyOf и allOf.
Пытаясь сделать это, я наткнулся на эту библиотеку GoogleAPI googleapis / gnostic, описание которой:
Этот репозиторий содержит инструмент командной строки Go, который преобразует описания OpenAPI JSON и YAML в эквивалентные представления буфера протокола и обратно.
На первый взгляд кажется, что это в точности решает мою проблему, но, как оказалось, эта библиотека преобразует только двоичный буфер протокола (protobuf) (.pb
) и файлы Swagger 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
может отображаться некорректно, откройте его здесь. Так что-то вроде:
�status��
��string
похоже:
<0x06>status<0x12><0x0b>
Ê<0x01><0x06>string
Для примера выше я сначала написал спецификацию чванства, а затем сгенерировал .pb
, но то же самое можно сделать и наоборот.
Текущее состояние:
Если у меня есть способ конвертировать файлы (.pb
) и (.proto
), цикл преобразования будет закрыт и завершен (.proto
-> .pb
-> .json/.yaml
-> .pb
-> .proto
).
Я уверен, что должен быть способ добиться этого, и, следовательно, существует решение моей исходной проблемы. Но я не смог найти ни одной статьи или фрагмента кода, который бы это делал. Есть ли разумные способы взаимного преобразования файлов .pb
и .proto
?
Если у вас есть решение, совершенно отличное от моего первоначального варианта использования, пожалуйста, поделитесь им. Это бы очень помогло.
Заранее спасибо!
Редактирует:
(1) Благодаря недавним комментариям становится ясно, что «преобразование» между .pb
и .proto
- это в первую очередь абсурдный вопрос. Но исходная проблема остается той же, то есть как сгенерировать спецификацию swagger3 (OpenAPI3) из файла protobuf (.proto
), используя аннотации, теги или иным образом. Соответствующее изменение заголовка вопроса.
(2) Буквально на следующий день после того, как я разместил это, я наткнулся на репозиторий gnostic-grpc, описание которого говорит:
Этот инструмент преобразует описание API OpenAPI v3.0 в описание службы gRPC, которую можно использовать для реализации этого API с помощью перекодирования gRPC-JSON.
Опять же, это слишком рано заставило меня выйти. На самом деле, это был проект GSOC, и, как ни удивительна идея этого репозитория, он не выполняет требования. Более того, это не библиотека для взаимного преобразования, и она очень незрелая для любого производственного использования. Фактически, он не может предоставить некоторые из основных фундаментальных функций спецификации OpenAPI3.
Но это хранилище движется в правильном направлении. Я пришел к выводу, что для этого нужен специальный плагин, в основном за счет расширения библиотеки аннотаций в GO.
(3) По-видимому, нет хороших и очевидных кандидатов для преобразования из .proto
в спецификацию OpenAPI3 (.yaml/.json
), за исключением gnostic- grpc, который очень незрелый и в настоящее время находится в стадии разработки для любого реального использования.
Но для обратного преобразования, то есть спецификации OpenAPI3 (.yaml/.json
) в .proto
, есть хорошая библиотека под названием openapi-generator в OpenAPITools, который преобразует спецификацию OpenAPI v2 / 3 в заглушки клиент / сервер почти для всех платформ. Но поскольку это не исходный вопрос, вопрос все еще остается открытым.