gRPC transport for trooba pipeline.
The module provides a client and service side gRPC transport implementation for trooba pipeline.
- Contributing: Pull requests are welcome!
- Read
CONTRIBUTING.md
and check out our bite-sized and help-wanted issues - Submit github issues for any feature enhancements, bugs or documentation problems
- Read
- Support: Join our gitter chat to ask questions to get support from the maintainers and other Trooba developers
- Questions/comments can also be posted as github issues
npm install trooba-grpc-transport --save
var port = 50001;
var grpcTransport = require('trooba-grpc-transport');
require('trooba')
.use(grpcTransport, {
protocol: 'http:',
hostname: 'localhost',
port: port,
proto: require.resolve('path/to/hello.proto'),
connectTimeout: 100,
socketTimeout: 1000
})
.build()
.create('client:default')
.hello({
name: 'Bob'
}, function (err, response) {
console.log(err, response)
});
syntax = "proto3";
// The hello service definition.
service Hello {
// Sends a greeting
rpc SayHello ( HelloRequest) returns ( HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
var pipeServer = Trooba.use(transport, {
port: port,
hostname: 'localhost',
proto: Grpc.loadPackageDefinition(GrpcProtoLoader.loadSync(require.resolve('./path/to/hello.proto')))
})
.use(function handler(pipe) {
pipe.on('request', (request, next) => {
// do something with request
console.log('gRPC request metadata:', request.headers);
next();
});
pipe.on('request:data', (data, next) => {
// do something with request stream data chunk
console.log('request chunk:', data);
next();
});
pipe.on('request:end', (data, next) => {
// do something with stream end
console.log('end of request stream');
next();
});
pipe.on('response', (response, next) => {
// do something with response
console.log('gRPC response metadata:', response.headers);
next();
});
pipe.on('response:data', (data, next) => {
// do something with response stream data chunk
console.log('response chunk:', data);
next();
});
pipe.on('response:end', (data, next) => {
// do something with end of response stream
console.log('end of response stream');
next();
});
})
.use(function controller(pipe) {
// handle request/response here
pipe.on('request', request => {
pipe.respond({
body: 'Hello ' + request.body.name
});
});
});
const app = pipeServer.build('server:default');
svr = app.listen();
console.log('toorba service is listening on port:', port);
The module exports service and client API which matches exactly the API provided by gRPC module.
Once request/response/data chunk enters the trooba pipeline, it assumes more generic API and request like data structures.
Trooba framework does not dictate specific data structures that should be used for request/response/messages/stream objects. It assumes basic requirements and leaves everything else to the implementor of the transport.
This transport goes further and defines some specifics for data it operates with:
- Possible flows:
- request/response is a basic interaction between client and service
- request/stream is a flow where for a single request it results in response stream
- stream/response is a flow where for request stream the backend generates a single response
- stream/stream is a flow where for the request stream the backend generates a response stream
- All the above flows use request and response object to initiate the flow and streaming uses arbitrary data chunks
- Request object structure:
- body contains request data which is a message object in gRPC terms
- headers contains request headers that match gRPC metadata
- path matches gRPC package namespace and service name separated by '/'. For example:
'foo.bar.v1.Hello.sayHello' => '/foo/bar/v1/Hello/sayHello'
- Response object structure:
- body contains response data which is a message object in gRPC terms
- headers contains response headers that match gRPC metadata
- status is gRPC status
- Data chunk matches gRPC streaming data
The client transport uses two timeouts:
- connectTimeout sets the deadline for establishing the connection
- socketTimeout sets the deadline for response or any further response chunk; whenever a new chunk is received the transport resets the socket timeout
For more advanced examples, please take a look at unit tests You can also find an implementation of simple service router here.
- Router example:
module.exports = function routes() {
var router = Router.create();
router.use({
path: 'com/xyz/helloworld/Hello/sayHello',
handle: require('./sayHello')
});
router.use({
path: 'Hello/sayHello',
handle: require('./sayHello')
});
router.use({
path: 'Hello/sayHelloAll',
handle: require('./sayHelloAll')
});
router.use({
path: 'Hello/beGreeted',
handle: require('./beGreeted')
});
return router.build();
};
- Service:
var pipeServer = Trooba
.use(transport, {
port: 40000,
hostname: 'localhost',
proto: Server.proto
})
.use(routes());
// create an app
var app = pipeServer.build().create('server:default');
// start it
app.listen(() => {
console.log('The server is ready');
});