Нельзя просто взять и написать структуры (классы) доступа к данным Protocol Buffers. gRPC API начинается со спецификации. HTTP API может существовать и без спецификации. Тем не менее, по понятным причинам, трудно найти коммерческий HTTP API без какого-нибудь OpenAPI (он же Swagger, он же Гога, он же Жора). В экосистеме gRPC есть инструмент по имени grpc-gateway, который может оказаться очень полезным в случае необходимости "прикрутить" HTTP JSON API к gRPC API. Он позволяет генерировать код reverse-proxy, а также спецификацию в формате OpenAPI, используя определения в файлах .proto, что упрощает как разработку, так и поддержку.
Далее расскажу как можно приготовить подобный HTTP API.
Для примера используем код со страницы Quick Start. В итоге получим сервис, который работает по обоим протоколам, и, в качестве вишенки на торте, предлагает Swagger UI. Для сборки используем Mage. TL;DR: исходный код.
Let's Get Ready To Rumble!
Шаг 1. gRPC.
В финале первого шага структура проекта будет выглядеть так:
1.1 - Пишем код структуры, которая реализует основной юзкейс сервиса - приветствие.
- greeter/greeter.go
1.2 - Копируем код файла определения сервиса Greeter из мануала.
- proto/hello.proto
1.3 - Создаем magefile, пишем скрипт Build для генерации gRPC stub.
- magefile.go
1.4 - Генерируем файл proto/hello.pb.go.
1.5 - Реализуем GreeterServer.
- server/grpc/greeter.go
1.6 - Пишем обертку gRPC сервера.
- server/grpc/server.go
1.7 - Создаем файл с кодом для запуска приложения.
- server/server.go
1.8 - И наконец package main.
- main.go
Запускаем приложение.
Для теста пишем код gRPC клиента.
- cmd/client/grpc/main.go
Отправляем приложению запрос по gRPC.
So far so good.
Шаг 2. HTTP.
В финале второго шага структура проекта будет выглядеть так:
2.1 - В файл определения сервиса Greeter добавляем аннотации для генерации reverse-proxy и swagger definitions.
- proto/hello.proto
2.2 - В magefile редактируем скрипт Build для генерации не только gRPC stub, но и reverse-proxy и swagger definitions.
- magefile.go
2.3 - Генерируем файлы proto/hello.pb.go (gRPC stub), proto/hello.pb.gw.go (reverse-proxy) и proto/hello.swagger.json (swagger definitions).
2.4 - Пишем обертку HTTP сервера.
- server/http/server.go
2.5 - В файл с кодом для запуска приложения добавляем код для запуска HTTP сервера.
- server/server.go
2.6 - И наконец package main.
- main.go
Запускаем приложение.
Отправляем приложению запрос по gRPC.
Отправляем приложению запрос по HTTP.
Easy peasy.
Шаг 3. Swagger UI.
В финале третьего шага структура проекта будет выглядеть так:
3.1 - Копируем каталог dist из репозитория swagger-ui.
- third_party/swagger-ui
3.2 - Редактируем url в index.html - пишем путь к файлу proto/hello.swagger.json.
- third_party/swagger-ui/index.html
3.3 - Редактируем код обертки HTTP сервера для раздачи файлов из каталога third_party/swagger-ui, а также файла proto/hello.swagger.json.
- server/http/server.go
Запускаем приложение, открываем браузер, идем по адресу http://localhost:50052/apidoc/
Bingo!
И в завершение ложка дегтя.
На самом деле ничего страшного, все решаемо, но это уже совсем другая история...
Далее расскажу как можно приготовить подобный HTTP API.
Для примера используем код со страницы Quick Start. В итоге получим сервис, который работает по обоим протоколам, и, в качестве вишенки на торте, предлагает Swagger UI. Для сборки используем Mage. TL;DR: исходный код.
Let's Get Ready To Rumble!
Шаг 1. gRPC.
В финале первого шага структура проекта будет выглядеть так:
1.1 - Пишем код структуры, которая реализует основной юзкейс сервиса - приветствие.
- greeter/greeter.go
1.2 - Копируем код файла определения сервиса Greeter из мануала.
- proto/hello.proto
- magefile.go
1.4 - Генерируем файл proto/hello.pb.go.
1.5 - Реализуем GreeterServer.
- server/grpc/greeter.go
1.6 - Пишем обертку gRPC сервера.
- server/grpc/server.go
1.7 - Создаем файл с кодом для запуска приложения.
- server/server.go
1.8 - И наконец package main.
- main.go
Запускаем приложение.
Для теста пишем код gRPC клиента.
- cmd/client/grpc/main.go
Отправляем приложению запрос по gRPC.
So far so good.
Шаг 2. HTTP.
В финале второго шага структура проекта будет выглядеть так:
2.1 - В файл определения сервиса Greeter добавляем аннотации для генерации reverse-proxy и swagger definitions.
- proto/hello.proto
2.2 - В magefile редактируем скрипт Build для генерации не только gRPC stub, но и reverse-proxy и swagger definitions.
- magefile.go
2.3 - Генерируем файлы proto/hello.pb.go (gRPC stub), proto/hello.pb.gw.go (reverse-proxy) и proto/hello.swagger.json (swagger definitions).
2.4 - Пишем обертку HTTP сервера.
- server/http/server.go
2.5 - В файл с кодом для запуска приложения добавляем код для запуска HTTP сервера.
- server/server.go
2.6 - И наконец package main.
- main.go
Запускаем приложение.
Отправляем приложению запрос по gRPC.
Отправляем приложению запрос по HTTP.
Easy peasy.
Шаг 3. Swagger UI.
В финале третьего шага структура проекта будет выглядеть так:
3.1 - Копируем каталог dist из репозитория swagger-ui.
- third_party/swagger-ui
3.2 - Редактируем url в index.html - пишем путь к файлу proto/hello.swagger.json.
- third_party/swagger-ui/index.html
3.3 - Редактируем код обертки HTTP сервера для раздачи файлов из каталога third_party/swagger-ui, а также файла proto/hello.swagger.json.
- server/http/server.go
Запускаем приложение, открываем браузер, идем по адресу http://localhost:50052/apidoc/
Bingo!
И в завершение ложка дегтя.
На самом деле ничего страшного, все решаемо, но это уже совсем другая история...
Комментариев нет:
Отправить комментарий
Комментарий будет опубликован после модерации