GRPC не удается сериализовать объект с произвольными свойствами

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

Я использую @grpc/grpc-js и @grpc/proto-loader. Я уже настроил его на возврат произвольных скалярных значений, а также массивов и объектов с известной схемой. Все работало, пока я не дошел до той части, где мне хотелось генерировать произвольные объекты (то есть карты). По какой-то причине сервер gRPC не распознает объект, который я ему передаю, как объект и жалуется.

Ошибка, сообщенная клиентом:

Error: 13 INTERNAL: Error serializing response: .Result.testObject: object expected
    at callErrorFromStatus (***/test/grpc/node_modules/@grpc/grpc-js/build/src/call.js:31:19)
    at Object.onReceiveStatus (***/test/grpc/node_modules/@grpc/grpc-js/build/src/client.js:192:76)
    at Object.onReceiveStatus (***/test/grpc/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:360:141)
    at Object.onReceiveStatus (***/test/grpc/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:323:181)
    at ***/test/grpc/node_modules/@grpc/grpc-js/build/src/resolving-call.js:99:78
    at process.processTicksAndRejections (node:internal/process/task_queues:77:11)
for call at
    at ServiceClientImpl.makeUnaryRequest (***/test/grpc/node_modules/@grpc/grpc-js/build/src/client.js:160:32)
    at ServiceClientImpl.<anonymous> (***/test/grpc/node_modules/@grpc/grpc-js/build/src/make-client.js:105:19)
    at file://***/test/grpc/index.mjs:14:10
    at file://***/test/grpc/index.mjs:18:3
    at ModuleJob.run (node:internal/modules/esm/module_job:217:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:316:24)
    at async loadESM (node:internal/process/esm_loader:34:7)
    at async handleMainPromise (node:internal/modules/run_main:66:12) {
  code: 13,
  details: 'Error serializing response: .Result.testObject: object expected',
  metadata: Metadata {
    internalRepr: Map(2) { 'content-type' => [Array], 'date' => [Array] },
    options: {}
  }
}

Это мой файл прототипа (одинаковый как для клиента, так и для сервера):

syntax = "proto3";

service TestApi {
  rpc Execute(None) returns (Result);
}

message None {}

message Result {
  map<string, Value> testObject = 1;
}

message Value {
  oneof kind {
    bool boolValue = 1;
    int32 intValue = 2;
    double doubleValue = 3;
    string stringValue = 4;
  }
}

Функция-обработчик сервера:

export function handler(call, callback) {
  try {
    const response = generateValues('$', outputs); // Generate random response
    console.info(response);
    callback(null, response);
  } catch (e) {
    console.error(e);
    callback(e, null);
  }
}

console.error никогда не срабатывает. Пример вывода console.info:

{
  testObject: {
    VmZWD: false,
    VXiRwi: 28.087891844342792,
    cjCTDFD: false,
    inYZS: 6,
    AYKahk: ' xsyflf szsnwb ush',
    pgUT: 23.19160119367565
  }
}

Вещи, которые я пробовал, привели к той же ошибке:

  • Изменение Value на google.protobuf.Any (с соответствующим импортом)
  • Установка для параметров json, object и oneOf функции загрузки proto-loader значений true или false.

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

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
239
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Создаваемый вами объект не соответствует определенным вами типам сообщений. Поле карты testObject имеет тип значения Value, который определяется как сообщение, содержащее одно из нескольких полей. В вашем примере объекта ответа ключ VmZWD имеет значение false, но сообщение Value, представляющее значение false, будет представлено как { boolValue: false }. Все записи карты имеют одну и ту же проблему.

А что, если я установлю тип Any?

Abion47 09.03.2024 02:26

Сообщение Any содержит другое сериализованное сообщение типа, указанного в самом сообщении. Таким образом, это фактически добавит еще один уровень инкапсуляции для каждого значения, и вам нужно будет выполнить еще одну операцию сериализации и десериализации для каждого значения. Просто оберните каждое значение в объект Value, чтобы он соответствовал определению сообщения.

murgatroid99 09.03.2024 02:30

Другие вопросы по теме