Страницы

пятница, 29 марта 2019 г.

Golang RESTful gRPC

Нельзя просто взять и написать структуры (классы) доступа к данным Protocol BuffersgRPC 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!

И в завершение ложка дегтя.

На самом деле ничего страшного, все решаемо, но это уже совсем другая история...

Комментариев нет:

Отправить комментарий

Комментарий будет опубликован после модерации