Люди смотрят на меня как на сумасшедшего, когда я говорю о gRPC в клиентских веб-приложениях! Ну, если вы тоже не в курсе, это вполне возможно и, возможно, будущее веб-разработки. В этой статье мы рассмотрим эту тему, но постараемся быть краткими и охватить только основные полезные концепции. В конце статьи также есть ссылка на репозиторий Github в качестве примера кода.
Я предполагаю, что вы здесь, потому что знаете, что такое gRPC и буферы протоколов, почему они используются, поэтому вы ищете способ используйте их в своем внешнем приложении. Когда я начинал таким образом, я не находил материалов в Интернете полезными и не мог найти простого руководства. Так что мне пришлось научиться кое-чему самостоятельно, и вот мы здесь!

Инструменты и зависимости

Чтобы делать RPC-запросы к gRPC-серверу, вам нужны две зависимости в вашем проекте: grpc-web и google-protobuf. Его можно легко установить с помощью npm или любого другого менеджера пакетов.
Кроме того, вам необходимо установить в системе два подключаемых модуля: protoc и protoc-gen-grpc- web. Если вы работаете в Linux, вы можете легко установить protoc с помощью apt:

sudo apt install -y protobuf-compiler

Убедитесь, что они являются исполняемыми и их можно обнаружить из вашего PATH. Для пользователей Linux:

$ sudo mv ~/Downloads/protoc-gen-grpc-web-1.3.1-linux-x86_64 /usr/local/bin/protoc-gen-grpc-web
$ sudo chmod +x /usr/local/ bin/protoc-gen-grpc-web

Это все на данный момент! Вы полностью настроены.

Скомпилировать прототипы

Теперь вы можете легко скомпилировать файлы .proto и начать делать запросы. Используйте эту команду в каталоге вашего проекта:

$ protoc -I=$DIR echo.proto \
— js_out=import_style=commonjs:$OUT_DIR \
— grpc-web_out=import_style=commonjs,mode=grpcwebtext:$OUT_DIR

Здесь мы использовали стиль импорта полного машинописного текста и проводной формат grpc-web-text. Для получения дополнительной информации обратитесь к документации grpc-web.
Если вы используете eslint в своем проекте, не забудьте поместить сгенерированные файлы в свой файл eslintignore. Альтернативой является вставка /* eslint-disable */ в начале каждого сгенерированного файла.

Начать выполнение запросов RPC

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

Первый шаг: Установите необходимые значения

Есть два основных сгенерированных файла. При использовании стиля импорта машинописного текста также включается файл .d.ts для типизации.
• SampleServiceClientPb: он создает класс, который вам нужен для создания его экземпляра и передачи по крайней мере одного аргумента, который является URL-адресом хоста. Это первый шаг.
• sample_pb: компилятор создает класс для каждого объявления сообщения в вашем прото-файле. Вам нужно импортировать эти классы и создать экземпляры всех из них. Обратите внимание, что если у вас есть вложенные сообщения (объявление сообщения внутри объявления другого сообщения), вам также необходимо создать их экземпляры. Это необходимо, потому что вам нужно установить значения для всех параметров, верно?

Некоторые полезные методы, которые вы должны уметь использовать:
• setFoo(): этот метод используется для установки значения foo.
• setFooList(): этот метод генерируется, только если параметр повторяется. С помощью этого метода вы можете легко установить массив значений. Если тип параметра является самим другим сообщением, вам необходимо обработать его как отдельное сообщение, а затем установить его как параметр. Просто подумайте об этом как о порядке операций в математике. Объявление вложенного сообщения действует как вложенные круглые скобки.
• addFoo(): этот метод используется, когда вы хотите добавить значение к списку foo.
• toObject(): этот метод возвращает объектное представление сообщение. Это полезно, когда вы получаете данные с сервера и хотите показать их в своем приложении. Допустим, ответ представляет собой список элементов, и его необходимо преобразовать в объект JavaScript, чтобы иметь возможность отображать список в вашем компоненте.

Второй шаг: Форма запроса

Унарные методы вызова создаются в стиле обратного вызова. Вы должны написать функцию обещания, чтобы сделать ее стиле обещания JavaScript. Я сделал это в демонстрации, представленной в конце статьи.
Метод вызова принадлежит классу SampleClient, который вы ранее импортировали из файла SampleServiceClientPb на первом шаге.

Последний шаг: Чистый код!

Этот шаг не имеет прямого отношения к gRPC. При работе с API во внешнем приложении необходимо объявить асинхронные функции для каждого API. Функция принимает аргумент в качестве полезной нагрузки и возвращает полученные данные. Полезной нагрузкой может быть пользовательский ввод или что-то еще. Старайтесь держать все отдельно. Создайте отдельную папку для своих API. Создайте отдельные файлы для разных разделов вашего приложения. Каждый файл должен состоять из нескольких асинхронных функций, каждая из которых представляет один API. Импортируйте эти функции в свои компоненты и максимально используйте методы then, catch и finally и делайте все, что хотите. будь то отправка действия, отображение уведомления пользователю или что-то еще. Этот простой шаблон очень хорошо поможет вам сохранить все отдельно. Как только вы построите свое приложение на этом принципе, вы не будете делать свои компоненты уродливыми, а ваши функции будут пригодными для повторного использования и аккуратными.
В нашем случае, как только вы обещаете вызов метода, ваша функция вызова RPC будет асинхронной с использованием async и await.

Удачного кодирования!

Это все на данный момент! Я оставляю ссылку на репозиторий Github ниже, как упоминал ранее. Это шаблонный шаблон react-gpc. Я постараюсь время от времени вносить свой вклад в проект и делать больше примеров, чтобы охватить все, что мы описали в этой статье.
https://github.com/mehran-hrajabi/react-grpc-boilerplate

Дайте мне знать, что вы думаете!