Невозможно импортировать прототип Google с помощью @grpc/proto-loader
У меня есть следующий прото:
syntax = "proto3";
import "google/rpc/status.proto";
message Response {
google.rpc.Status status = 1;
}
message Request {
Type name = 1;
}
service Service {
rpc SomeMethod (Request) returns (Response);
}
И я пишу клиент в узле:
const path = require('path');
const grpc = require('grpc');
const protoLoader = require('@grpc/proto-loader');
const protoFiles = require('google-proto-files');
const PROTO_PATH = path.join(__dirname, '/proto/myproto.proto');
const packageDefinition = protoLoader.loadSync(
PROTO_PATH,
{
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true,
includeDirs: [protoFiles('rpc')],
},
);
const proto = grpc.loadPackageDefinition(packageDefinition);
const client = new proto.Service('localhost:1111', grpc.credentials.createInsecure());
Когда я запускаю клиент, я получаю следующую ошибку: TypeError: proto.Service не является конструктором. Я обнаружил, что это связано с импортом status.proto. Как правильно импортировать прототипы Google с помощью прото-загрузчика? Сервер находится на Java.
2 ответа
Ольга, вы не можете использовать абсолютный путь в PROTO_PATH, если вы используете includeDirs. Очевидно, вам нужно поместить оба пути, то есть путь к myproto.proto И путь к google-proto-файлам, в includeDirs и использовать просто имя файла в качестве PROTO_PATH, тогда он будет работать просто отлично. Посмотреть здесь:
https://github.com/grpc/grpc-node/issues/470
Вот модифицированный код, который работает. Обратите внимание, что мне также пришлось заменить "Type" на "int32" в myproto.proto.
const path = require('path');
const grpc = require('grpc');
const protoLoader = require('@grpc/proto-loader');
const protoFiles = require('google-proto-files');
const PROTO_PATH = 'myproto.proto';
const packageDefinition = protoLoader.loadSync(
PROTO_PATH,
{
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true,
includeDirs: ['node_modules/google-proto-files', 'proto']
},
);
const protoDescriptor = grpc.loadPackageDefinition(packageDefinition);
const client = new protoDescriptor.Service('localhost:1111', grpc.credentials.createInsecure());
Надеюсь, поможет.:)
Проблема здесь в том, что путь, который protoFiles('rpc')
возврат не работает с import
линия в вашем .proto
файл. Эта строка импорта означает, что @grpc/proto-loader
ищет каталог включения, который содержит google/rpc/status.proto
, но protoFiles('rpc')
возвращает каталог, который непосредственно содержит status.proto
, Таким образом, вы должны изменить одну или обе эти вещи, чтобы относительные каталоги соответствовали должным образом.