Typescript Grpc Service
Sun 10th November 2019
This weekend I thought I would play with typescript and GRPC a little. It seems docs on getting this up and running is a bit thin on the ground, so that makes it perfect candidate for a little blog post.
You can find example code here
To get started we need to create project, do so with the following commands
mkdir grpc-project
yarn init
mkdir -p src/proto
yarn add typescript ts-node grpc grpc-tools ts-protoc-gen @grpc/proto-loader
now we will want to create a protoc service so we can do some tasty code generation, here is an example proto file to get started
// service.proto
syntax = "proto3";
message Message {
string message = 1;
}
service Greeter {
rpc greet (Message) returns (Message) {}
}
sweet, now we want to get a little typescript going, to do this we want a tsconfig.json file so the compiler knows how to compile your code.
// tsconfig.json
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"sourceMap": true
}
}
then we want to generate the code that will help us use this proto file in our typescript code. Add the following to package.json
{
...
"scripts": {
"proto": "grpc_tools_node_protoc --plugin=protoc-gen-grpc=./node_modules/.bin/grpc_tools_node_protoc_plugin --plugin=protoc-gen-ts=./node_modules/.bin/protoc-gen-ts -I . ./service.proto --js_out='import_style=commonjs,binary:src/proto' --grpc_out=src/proto --ts_out='service=grpc-node:src/proto'"
}
...
}
now you can run the code generation using
yarn proto
and you should see the code appear in src/proto/
now we want to write our server code, here is an example to get you started
// src/index.ts
import { Message } from "./proto/service_pb";
import * as grpc from "grpc";
import { GreeterService } from "./proto/service_grpc_pb";
function greet(
call: grpc.ServerUnaryCall<Message>,
callback: grpc.requestCallback<Message>
) {
const resp = new Message();
resp.setMessage(`hello ${call.request.getMessage()}`);
callback(null, resp);
}
function main() {
const server = new grpc.Server();
server.addService(GreeterService, {
greet: greet
});
const bindto = `0.0.0.0:50051`;
server.bind(bindto, grpc.ServerCredentials.createInsecure());
console.log(`STARTING SERVER ON ${bindto}`);
server.start();
}
main();
we can run this with
yarn run ts-node src/index.ts
and to create a basic client
// src/client.ts
import { message } from "./proto/service_pb";
import * as grpc from "grpc";
import { greeterclient } from "./proto/service_grpc_pb";
function main() {
const client = new greeterclient(
"0.0.0.0:50051",
grpc.credentials.createinsecure()
);
const request = new message();
request.setmessage("max");
client.greet(request, (error: grpc.serviceerror, value: message) => {
if (error != null) {
console.log(error);
return
}
console.log(value.getmessage());
});
}
main();
similarly run this in a separate terminal with
yarn run ts-node src/client.ts
yarn run v1.19.1
$ /home/max/workspace/quora/grpc-typescript-example/node_modules/.bin/ts-node src/client.ts
hello Max
Done in 1.03s.
And there we have it, a basic grpc endpoint in typescript!