Skip to content

xizhibei/grpc-helper

Repository files navigation

gRPC helper

gRPC helper is an improved gRPC client with lots of helpful features.

Build Status Coverage Status npm version Dependency Status npm

Getting Started

Installing

npm i grpc-helper --save

or

yarn add grpc-helper

Features

  • Promised unary & client stream call
  • Client Load balance
  • Service health checking
  • Service discovery (static, dns srv)
  • Circuit breaker based on Brakes
  • Retry based on async-retry
  • Metrics for prometheus based on prom-client
  • Highly custom options

Usage

DNS Service discovery

const helper = new GRPCHelper({
  packageName: 'helloworld',
  serviceName: 'Greeter',
  protoPath: path.resolve(__dirname, './fixtures/hello.proto'),
  // intervalMs will determine how frequent the resolver lookup the records
  sdUri: 'dns://_grpc._tcp.greeter?intervalMs=5000',
});

await helper.waitForReady();

const res = await helper.SayHello({
  name: 'foo',
});

Static Service discovery

const helper = new GRPCHelper({
  packageName: 'helloworld',
  serviceName: 'Greeter',
  protoPath: path.resolve(__dirname, './fixtures/hello.proto'),
  sdUri: 'static://localhost:50051,localhost:50052,localhost:50053',
});

await helper.waitForReady();

const res = await helper.SayHello({
  name: 'foo',
});

Resolve with full response

const helper = new GRPCHelper({
  packageName: 'helloworld',
  serviceName: 'Greeter',
  protoPath: path.resolve(__dirname, './fixtures/hello.proto'),
  sdUri: 'static://localhost:50051',
  resolveFullResponse: true,
});

await helper.waitForReady();

const { message, peer, status, metadata } = await helper.SayHello({
  name: 'foo',
});

Client stream call

const stream = new stream.PassThrough({ objectMode: true });

const promise = helper.SayMultiHello(stream);

stream.write({
  name: 'foo1',
});

stream.write({
  name: 'foo2',
});

stream.write({
  name: 'foo3',
});

stream.end();

const result = await promise; // { message: 'hello foo1,foo2,foo3' }

Retry

const helper = new GRPCHelper({
  packageName: 'helloworld',
  serviceName: 'Greeter',
  protoPath: path.resolve(__dirname, './fixtures/hello.proto'),
  sdUri: 'static://localhost:50051',
  retryOpts: {
    enable: true,
    retries: 5,
    bailError(err, attempt) {
      // Just for example !!! It will not retry when code is 2
      return err.code === 2;
    },
  },
});

await helper.waitForReady();

await helper.SayHello({
  name: 'foo',
});

More

Please take a look at the test folder for more examples.

TODO

  • Better api
  • Doc
  • Test code
  • Retry on lb level when error
  • Auto load proto when only one service available
  • Consul/etcd/zk service discovery

License

This project is licensed under the MIT License - see the LICENSE file for details