gRPC — современный фреймвок для удалённого вызова процедур, разработанный Google в 2015 году. Им начинает пользоваться всё большее количество компаний по всему миру. В России, например, это Яндекс. gRPCurl — инструмент командной строки, написанный на Go. Он разработан компанией FullStory и позволяет взаимодействовать с gRPC серверами. В этой статье будут раскрыты особенности проекта и описаны основные кейсы для его применения.


Основная проблема, которую решает проект, это — использование двоичной кодировки по сети, так называемые буферы протоколов или protobufs. Это делает практически невозможным использование популярного curl. gRPCurl принимает на вход данные в формате JSON, после чего отправляет их на сервер. Кроме того, инструмент используется и в других проектах, где нужны его динамические вызовы, например, в gRPCox, который представляет графический интерфейс в браузере для запросов по gRPC.

Важно отметить, что данный инструмент позволяет просматривать схему gRPC с помощью запросов к серверу, который поддерживает отражение, и чтения исходных файлов прототипов, либо загрузки скомпилированных файлов прототипов (файлы, содержащие прототипы закодированных файловых дескрипторов). В общем и целом, это тот же способ, который используется для конвертирования отправляемого JSON-файла в protobuf. В случае, когда сервер не поддерживает отражение, необходимо использовать исходные файлы прототипов, которые определяют службу или которые может использовать gRPCurl.

Фичи


  • Поддержка всех видов методов gRPC, включая методы потоковой передачи
  • Возможность управления методами двунаправленной потоковой передачи в интерактивном режиме
  • Поддежрка TLS-серверов, серверов без TLS и TLS, требующего сертификатов от клиента
  • Возможность работать с серверами, не поддерживающими отражение, с помощью файлов .proto или файлов прототипов
  • Использование stdin в теле запроса

Начало работы


gRPCurl поддерживает установку через Docker, HomeBrew, исходные и бинарные файлы. Процесс подробно описан в документации.

Самое простое, что можно сделать с помощью данного инструмента — это вызвать RPC на доверенном сервере, который поддерживает отражение и не требует сертификатов от клиента. Следующий листинг иллюстрирует отправку пустого запроса на grpc.server.com.

  # С TLS
  grpcurl grpc.server.com:443 my.custom.server.Service/Method

  # без TLS
  grpcurl -plaintext grpc.server.com:80 my.custom.server.Service/Method

Чтобы отправить JSON в теле запроса, необходимо воспользоваться флагом -d. Следует заметить, что все флаги должны следовать перед названиями сервера и метода.

  grpcurl -d '{"id": 4532, "cities": ["Moscow","New York"]}'     grpc.server.com:443 my.custom.server.service/method

В примере видно, что тело запроса должно быть в формате JSON. После выполнения команды оно будет конвертировано в protobuf. В случае, когда необходимо включить gRPCurl в другую команду, например, jq, то можно использовать флаг -d @, который сообщает программе считывать тело запроса из stdin:

  grpcurl -d @ grpc.server.com:443 my.custom.server.Service/Method <<EOM
  {
    "id": 453,
    "tags": [
      "Moscow",
      "New York"
    ]
  }
  EOM

Для получения списка всех доступных методов у сервера нужно использовать команду list. При использовании исходных файлов .proto или файлов протоколов вместо отражения сервера будут перечислены все службы, определённые в файлах источника или протоколов.

  # Сервер поддерживает отражение
  grpcurl localhost:8787 list

  # Использование скомпилированных файлов протоколов
  grpcurl -protoset my-protos.bin list

  # Использование .proto файлов
  grpcurl -import-path ../protos -proto my-stuff.proto list

Кроме этого существует возможность получить список методов выбранного сервиса:

  grpcurl localhost:8787 list my.custom.server.Service

Для отображения информации о сервисе необходимо использовать команду describe, которая выведет данные на основании знаний сервера или прототипа. Также будет отображено описание сервиса в виде фрагментов исходного кода:

  # Сервер поддерживает отражение
  grpcurl localhost:8787 describe my.custom.server.Service.MethodOne

  # Использование скомпилированных файлов протоколов
  grpcurl -protoset my-protos.bin describe my.custom.server.Service.MethodOne

  # Использование .proto файлов
  grpcurl -import-path ../protos -proto my-stuff.proto describe my.custom.server.Service.MethodOne

Файловые дескрипторы


Дескрипторы необходимы для того, чтобы gRPCurl понимал схему сервера и мог конвертировать входные файлы в protobuf и переводить двоичные ответы сервера в текст.

Отражение сервера


Без дополнительных пользовательских настроек инструмент будет пытаться использовать отражение сервера. О том, как его можно настроить, можно прочитать в официальной документации.

При использовании данного способа подключения необходимо указывать хост и порт сервера или адрес Unix сокета. Это необходимо для работы программы и позволяет использовать такие команды, как describe и list.

Файлы .proto


Если же сервер не поддерживает отражение, то можно использовать флаг -proto, чтобы указать путь к файлу .proto. А в случае, когда нужно указать папки с необходимыми зависимости, нужно использовать флаг -import-path.

Как и при компиляции с помощью protoc нет необходимости в указывании путей для импорта стандартных протоколов, включённых в protoc. Эти файлы уже включены в gRPCurl, поскольку копии их дескрипторов встроены в двоичный файл gRPCurl.

Важно уточнить, что при использовании файлов .proto, можно не указывть хост и порт сервера или путь к сокету Unix, так как программе нужно обращаться только к исходным файлам прототипов.

Скомпилированные файлы прототипов


Кроме описанных выше методов подключения, существует способ, в котором используются уже скомпилированные файлы прототипов. Лучше всего использовать его, когда необходимо совершить множество вызовов gRPCurl, так как не будут затрачены ресурсы и время на компиляцию. Для создания таких файлов необходимо использовать protoc на файлах .proto:

  protoc --proto_path=.     --descriptor_set_out=myservice.protoset     --include_imports my/custom/server/service.proto

Флаг --descriptor_set_out сообщает protoc о создании прототипа, а флаг --include_imports необходим для того, чтобы прототип содержал всё, что необходимо gRPCurl для обработки данных.

В данном случае можно также не включать в запрос хост и порт, или сокет Unix.

Заключение


В данной статье была рассмотрена работа мощного инструмента gRPCurl, созданного для работы с gRPC серверами. Также описан процесс работы с данным инструментом и способы решения некоторых проблем.




На правах рекламы


Аренда выделенного сервера от 333 руб. в сутки, активация в течение минуты. Лучшее решение для ваших идей и проектов!

Подписывайтесь на наш чат в Telegram.