Expressive gRPC middleware framework for Node.js. It provides the same style of middleware system and APIs many developers are familiar with which is similar to Koa 2.
Node.js v7.6+ is required, the middleware system of Gora is based on async function.
Install via NPM:
npm install groa --saveThe same way with Koa to implement your first gRPC server:
constGroa=require('groa');constapp=newGroa();// Add proto fileapp.addProto(__dirname+'/example.proto');// Add middlewareapp.use(async(ctx,next)=>{// responsectx.body=ctx.req.body;});app.listen(50051,()=>{console.log('Listening on port 50051');});example.proto
syntax="proto3";
packageexample.foo;
serviceExample1 {
rpcPing(Ping) returns (Pong) {}
}
messagePing {
stringcontent=1;
}
messagePong {
stringcontent=1;
}Implement streaming method is quite easy that writing to Stream object of body directly.
constGroa=require('groa');constapp=newGroa();// Add proto fileapp.addProto(__dirname+'/stream.proto');constdelay=(interval)=>{returnnewPromise((resolve)=>{setTimeout(resolve,interval);});}// Add middlewareapp.use(async(ctx,next)=>{// send a messagectx.body.write({timestamp: newDate()});// delay 1 secondawaitdelay(1000);// send a messagectx.body.write({timestamp: newDate()});// delay 1 secondawaitdelay(1000);// completectx.body.end();});app.listen(50051,()=>{console.log('Listening on port 50051');});stream.proto
syntax="proto3";
packageexample.foo;
serviceExample1 {
rpcreceive(ReceiveRequest) returns (streamReceiveResponse) {};
}
messageReceiveRequest {
}
messageReceiveResponse {
stringtimestamp=1;
}When input is a stream, ctx.req.body will be a stream object for receiving data. Besides, ctx.body contains the same stream object with ctx.req.body if output is stream as well.
constGroa=require('groa');constapp=newGroa();// Add proto fileapp.addProto(__dirname+'/stream.proto');// Add middlewareapp.use(async(ctx,next)=>{// Alias as ctx.body for input streamctx.req.body.on('data',(data)=>{console.log(data);// Send the same data back to clientctx.body.write(data);});});app.listen(50051,()=>{console.log('Listening on port 50051');});stream.proto
syntax="proto3";
packageexample.foo;
serviceExample1 {
rpcreceive(streamReceiveRequest) returns (streamReceiveResponse) {};
}
messageReceiveRequest {
stringtimestamp=1;
}
messageReceiveResponse {
stringtimestamp=1;
}You can set status code and message when problem occurring for a request, the following is status code of gRPC Groa supported:
- OK: 0
- CANCELLED: 1
- UNKNOWN: 2
- INVALID_ARGUMENT: 3
- DEADLINE_EXCEEDED: 4
- NOT_FOUND: 5
- ALREADY_EXISTS: 6
- PERMISSION_DENIED: 7
- RESOURCE_EXHAUSTED: 8
- FAILED_PRECONDITION: 9
- ABORTED: 10
- OUT_OF_RANGE: 11
- UNIMPLEMENTED: 12
- INTERNAL: 13
- UNAVAILABLE: 14
- DATA_LOSS: 15
- UNAUTHENTICATED: 16
Usage:
ctx.status=Groa.status.ABORTED;ctx.message='Something\'s wrong'Or you can throw an error:
ctx.throw('wrong');// UNKNOWN if no status codectx.throw(Application.status.OUT_OF_RANGE);ctx.throw(Application.status.OUT_OF_RANGE,'OUT OF RANGE!!!');- Router: gora-router
Groa provide a Client class which provides Promise-style functions to make client much easier in ES6.
const{ Client }=require('groa');constclient=newClient('0.0.0.0',50051);constmain=async()=>{// Loading definition fileawaitclient.loadProto(__dirname+'/example.proto');// Get service defninedletExample1=client.getService('example.foo.Example1');// callletret=awaitExample1.ping({content: 'hello'});console.log(ret);};main();- Need more testcases
- Support google.api.http to generate restful API automatically
- Support SSL
Licensed under the MIT License
Copyright(c) 2017 Fred Chien(錢逢祥) <cfsghost@gmail.com>

