Go. REST или gRPC?

Andrew Minkin
Jan 8, 2019 · 4 min read

В этой статье поговорим о двух подходах и нескольких инструментах, чтобы сделать HTTP API в Go.

Глобально рассмотрим REST и gRPC и пройдемся по инструментарию.

REST

Многие не понимают REST и продолжают делать API в RPC стиле. Я сам таким был и такая ситуация складывается от незнания подхода. К сожалению, информации в вики не хватает, чтобы понять всю силу подхода и поэтому будет все больше и больше статей в блог и выступлений на конфах о том, что вы делаете REST неправильно.

Разобраться в том, что такое REST и как его готовить мне помог гайдлайн от Zalando. Этот документ появился примерно тогда же, когда и инициатива OpenAPI. Также появился Design First подход, где вы сначала описываете API и только после этого уже начинаете реализовывать бизнес логику. С документом можно ознакомиться тут.

Для построения REST API хорошо помогает swagger. Правда, инструментария в мире Go мало. Зато с ним очень удобно работать в каком-нибудь node.js. В случае с Go приходиться придумывать какие-то костыли в виде тестов, которые проверяют есть ли дока на эндпоинты, либо генераторы структур данных для Go из swagger.yml файла.

Как без полной поддержки swagger сделать полноценную и поддерживаемую REST API в Go?

Один из вариантов:

  1. Пишем swagger.yml

В конечном итоге получается так. Описываем модель, генерируем код, реализуем бизнес логику.

Также мы можем из swagger.yml генерировать модели дополнительно.

Все приложения c REST API в большинстве строятся по обычной трехзвенной архитектуре.

Обычно строил приложения с помощью echo фреймворка. У него хороший дизайн и нормальная скорость. Для слоя БД берем sqlx и с помощью этого набора и самописных кодогенераторов можно довольно быстро построить API. Хотя, все же порекомендую взять Python с какой-нибудь Django или Flask и на них сделать апишку. Но это в случае, если вам не нужно держать большую нагрузку.

gRPC

gRPC — инструмент от гугла, который активно пиарится и в го сообществе и за его пределами, позволяет делать хорошие внутренние API поверх HTTP/2 по умолчанию.

В gRPC много крутого функционала, но самая важная фича — это кодогенерация и пропаганда Design first подхода по умолчанию.

При использовании swagger есть большой соблазн не поддерживать доку, ведь это чаще всего дополнительный геморрой. При использовании gRPC этого не получится, потому что инструмент продуман более хорошо и он упрощает жизнь разработчику. У вас не получиться сгенерировать код, не написав proto файл и не расшарив его между командами разработки.

Идеальный вариант использования gRPC — это общение между микросервисами и построение коммуникации с сервером для мобильных приложений.

gRPC — это в первую очередь RPC фреймворк и он больше про методы в стиле UpdateBalance, GetClient и прочие. REST же — он про ресурсы. GET /users, POST /users и так далее. В gRPC можно спокойно пилить кучу методов, пока не упретесь в ограничение гошных интерфейсов в 512 метод на один интерфейс. Но обычно за это отрывают руки, потому что вовремя не вынесли часть логики в другой сервис.

Так как эта статья больше про gRPC, то давайте возьмем обычный helloworld пример из доки grpc-go и будем его дополнять плагинами. Мы добавим валидацию данных, REST API к gRPC сервису и будем генерировать swagger.json с документацией к нему.

syntax = "proto3";

package helloworld;

service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
string name = 1;
}

message HelloReply {
string message = 1;
}
  1. main.go — сервис, который будет конфигурировать и запускать наше приложение

Чтобы сгенерировать код, достаточно запустить

protoc --go_out=plugins=grpc:.

На первых порах для автоматизации рутины нам хватит несколько команд, описанных в Makefile.

Makefile нам нужен тут для того, чтобы всегда вводить make proto для генерации кода из протофайлов. К тому же эта часть будет расширятся и команд будет становиться больше и они будут длиннее.

Makefile нам нужен тут для того, чтобы всегда вводить make proto для генерации кода из протофайлов. К тому же эта часть будет расширятся и команд будет становиться больше и они будут длиннее.

server/server.go

Который запускается из main.go следующим образом

Который запускается из main.go следующим образом

gRPC-gateway или подружи REST с gRPC

gRPC-gateway или подружи REST с gRPC

Ранее мы уже сталкивались с этим инструментом, изучали его и даже сделали проект с помощью этого плагина. Поэтому вспомнили о нем, ведь нас ждала неприятная перспектива поддержки нескольких сервисов, которые делают одно и тоже. gRPC-gateway в этом случае нам очень помогает, потому что в одном протофайле у нас будет и gRPC и REST описание.

Устанавливаем его по инструкции, описанной в README, преобразуем наш протофайл в следующий вид

Также нам нужно поменять команду для генерации кода из протофайлов в следующий вид

Также нам нужно поменять команду для генерации кода из протофайлов в следующий вид

Теперь команда proto сгенерит нам интефейсы для реализации логики, rest gateway и swagger документацию.

Теперь команда proto сгенерит нам интефейсы для реализации логики, rest gateway и swagger документацию.

Модифицируем наш код для запуска сервера и приведем его в такой вид

Теперь мы запустим наш сервер и попробуем погонять rest запросы

Теперь мы запустим наш сервер и попробуем погонять rest запросы

Таким образом у нас получилась REST API поверх GRPC. Но в этом примере не хватает валидации. Для валидации мы будем использовать https://github.com/lyft/protoc-gen-validate. Следуя примерам в документации, приведем наш протофайл в следующий вид

Добавим еще одну команду для генерации нужного кода

Добавим еще одну команду для генерации нужного кода

После перегенерации кода, мы видим, что валидация теперь для нас работает.

Заключение

gRPC экосистема очень дружелюбна для web сервисов на Go. Благодаря ей, можно ускорять разработку сервисов, генерируя бОльшую часть кода, который повторяется из раза в раз. Полный код проекта можно посмотреть тут.

Если вы до сих пор пишете REST API и не знаете как хорошо документировать вашу API, то переходите на gRPC и экономьте время на программирование web сервисов на Go!

Mad Devs — блог об IT

Engineering your growth. Mad Devs is the team behind large scalable projects, globally.

Mad Devs — блог об IT

Mad Devs is a Cambridge-headquartered IT company developing enterprise-level software solutions for finance, transportation & logistics, security, edtech, and advertising industries. For more information about us, please browse our website: https://maddevs.io/

Andrew Minkin

Written by

Mad Devs — блог об IT

Mad Devs is a Cambridge-headquartered IT company developing enterprise-level software solutions for finance, transportation & logistics, security, edtech, and advertising industries. For more information about us, please browse our website: https://maddevs.io/

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store