Как стать автором
Обновить

gRPC — альтернатива REST API от Google

Время на прочтение4 мин
Количество просмотров31K

Проблема

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

Большая часть реализаций REST использует стандарт JSON для обмена сообщениями. Обычно это удобно - сама по себе такая структура легко читается людьми и предоставляет независимость от языка программирования.

Недостатками такого решения является избыточность данных и сущностей из которых состоит запрос. В большинстве случаев это некритично. Проблемы начинаются в сценариях, когда нужно передавать много данных с низкой задержкой.

Зачем нужен gRPC

gRPC (Remote Procedure Calls) — это система удалённого вызова процедур (RPC) с открытым исходным кодом, первоначально разработанная в Google. В качестве основного протокола передачи применяется HTTP/2, для описания процедур применяется “Protocol Buffers”. Это в свою очередь приносит дополнительные преимущества: сжатие HTTP-заголовков и мультиплексирование запросов.

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

Типичная реализация gRPC
Типичная реализация gRPC

Когда использовать gRPC

Статистика говорит о том, что gRPC используется гораздо реже, чем REST. К сожалению, часто только из-за этого разработчики выбирают REST. И если в небольших проектах это оправдано, тогда напрашивается вопрос: в каких случаях правильным выбором всё же будет gRPC?

Стоит взглянуть на таблицу их основных отличий.

Сравнение gRPC и REST

Технология

gRPC

REST

Протокол

http 2.0

http 1.1

Формат обмена данными

protobuf

JSON

Избыточность

Нет

Да

Декларативность

Единый .proto файл

Нет единого соглашения

Хотя REST подход также может использовать HTTP 2 для обмена данными, тем не менее он будет ограничен моделью запрос-ответ, при которой не применяется поддержка двусторонней потоковой передачи данных возможной для HTTP При этом, конечно же сохраняется возможность унарных взаимодействий, которые реализует HTTP 1.1 (один запрос - один ответ).

В конечном итоге мы получаем более высокую скорость ответа в разных сценариях.

Скорость ответа REST и gRPC
Скорость ответа REST и gRPC

При этом в gRPC наименования полей, ожидаемых запросов и возвращаемых ответов определяется и описывается в одном месте - в файле .proto. И если вы хотя бы раз разрешали конфликты в наименовании полей вида ObjectID и object_id, то вам определенно понравится работать с gRPC.

Пример .proto файла:

syntax = "proto3";

/* Наименование пакета данных */

message Calculator {

    int32 xxx = 1;

    int32 yyy = 2;

}

message CalculatorRequest {

    Calculator calculator = 1;

}

message CalculatorResponse {

    int32 result = 1;

}

Когда не использовать gRPC

gRPC при всех своих достоинствах не лишен недостатков. Вот парочка:

  • Использование HTTP/2 в gRPC, что делает невозможным реализацию клиента gRPC в браузере - вместо этого приходится использовать прокси. 

  • Более сложная отладка по сравнению с REST из-за бинарного обмена сообщениями

Реальный кейс

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

Мы делали реализацию API на Python, где использовали дуплексное (двунаправленное соединение) для сервиса потокового распознавания речи в текст.

Дуплексное соединение gRPC на Python:

def stream_recorder(self) -> Union[RecognitionRequest, str]:

    """Потоковый захват речи"""

    for _ in range(0, int(self.rate / self.chunk * self.seconds)):

        data = self.stream.read(self.chunk, exception_on_overflow=False)

        yield RecognitionRequest(audio=data)

def stream_recognize(self) -> str:

    """Потоковое распознавание речи"""

    credentials = grpc.ssl_channel_credentials()

    with grpc.secure_channel(f'{settings.SPEECH_SERVER}:{settings.SPEECH_PORT}',

                            credentials=credentials) as chennel:

        stub = VoiceAssistantServiceStub(chennel)

        metadata = [('authorization', f'Bearer {settings.SPEECH_API_TOKEN}'), ('audioformat', 'lpcm')]

        for response in stub.RecognizeAudio(self.stream_recorder(), metadata=metadata):

            if response.chunks[0].final:

                return response.chunks[0].text.strip()

Эти декларативные преимущества gRPC работают не только в момент написания кода. Особенно удобно делать отладку соединения в Postman, который предоставляет поддержку протокола. 

Даже не имея доступа к удаленному серверу мы можем имитировать запросы с моковыми данными и эмулировать ответ нажатием одной кнопки.

Поддержка gRPC в Postman
Поддержка gRPC в Postman

Выводы

В отличие от REST, gRPC - решение, которое не зависит от платформы и языка. И благодаря HTTP/2 и протоколу Protobuf решает проблемы, связанные со скоростью передачи данных, их весом, в результате повышая эффективность обмена сообщениями.

Теги:
Хабы:
Всего голосов 21: ↑10 и ↓11+3
Комментарии33

Публикации

Истории

Работа

Data Scientist
76 вакансий
Python разработчик
134 вакансии

Ближайшие события

27 августа – 7 октября
Премия digital-кейсов «Проксима»
МоскваОнлайн
11 сентября
Митап по BigData от Честного ЗНАКа
Санкт-ПетербургОнлайн
14 сентября
Конференция Practical ML Conf
МоскваОнлайн
19 сентября
CDI Conf 2024
Москва
24 сентября
Конференция Fin.Bot 2024
МоскваОнлайн
25 сентября
Конференция Yandex Scale 2024
МоскваОнлайн
28 – 29 сентября
Конференция E-CODE
МоскваОнлайн
28 сентября – 5 октября
О! Хакатон
Онлайн
30 сентября – 1 октября
Конференция фронтенд-разработчиков FrontendConf 2024
МоскваОнлайн