Страницы

суббота, 28 июля 2018 г.

Node.js gRPC defaults

Вчера обновил grpc-node и после запуска приложения получил предупреждение: 'DeprecationWarning: grpc.load: Use the @grpc/proto-loader module with grpc.loadPackageDefinition instead'. В процессе выяснения причины оказалось что grpc-protobufjs среди прочих решает вопрос с дефолтными значениями: по умолчанию отсутствие значения интерпретируется как отсутствие значения, т.е. полю не присваивается дефолтное значение. Конец моим страданиям и разочарованиям, теперь можно избавляться от костылей. Кроме того исследование изменений в gRPC позволило мне ответить еще на один на вопрос: как передать метаданные с сервера на клиента без использования ошибки.


- server.js:
const grpc = require('grpc')
const protoLoader = require('@grpc/proto-loader')
const path = require('path')
const protoFileName = path.join(__dirname, 'protos/test.proto')
const packageDefinition = protoLoader.loadSync(protoFileName)
const grpcObject = grpc.loadPackageDefinition(packageDefinition)
 
const hello = (call, cb) => {
  console.log('req:', call.request)
  const metadata = new grpc.Metadata()
  if (call.request.name) {
    metadata.set('statusCode', '200')
    call.sendMetadata(metadata)
    return cb(null, { message: `Hello, ${call.request.name}!` })
  }
  metadata.set('statusCode', '400')
  const err = new Error('Invalid name')
  err.metadata = metadata
  cb(err)
}
 
const server = new grpc.Server()
server.addService(grpcObject.test.Greeter.service, {
  hello: hello
})
server.bind('0.0.0.0:50051', grpc.ServerCredentials.createInsecure())
server.start()

- client.js:
const grpc = require('grpc')
const protoLoader = require('@grpc/proto-loader')
const path = require('path')
const protoFileName = path.join(__dirname, 'protos/test.proto')
const packageDefinition = protoLoader.loadSync(protoFileName)
const grpcObject = grpc.loadPackageDefinition(packageDefinition)
 
const hello = (client, name) => {
  let statusCode
  const call = client.hello({ name: name }, (err, res) => {
    if (err) {
      statusCode = Number(err.metadata.get('statusCode')[0])
      console.error('err:', { message: err.details })
    } else {
      console.log('res:', res)
    }
    console.log('statusCode:', statusCode)
  })
  call.on('metadata', (metadata) => {
    statusCode = Number(metadata.get('statusCode')[0])
  })
}
 
const client = new grpcObject.test.Greeter('localhost:50051', grpc.credentials.createInsecure())
hello(client, process.argv[2])



И наконец я открыл для себя вменяемую документацию по Node.js gRPC, еще пару месяцев назад ее точно не было.