


















Documentation for using grpc within node is split between static generation and dynamic generation. Dynamic generation compiles protobuffer definition files at runtime through protobuf.js and typically looks like the following:
var PROTO_PATH = __dirname + '/../../../protos/api.proto';
var grpc = require('@grpc/grpc-js');
var protoLoader = require('@grpc/proto-loader');
var packageDefinition = protoLoader.loadSync(
PROTO_PATH,
{keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
var protoDescriptor = grpc.loadPackageDefinition(packageDefinition);
Most of the grpc docs use the dynamic approach - I assume for ease of getting started. The main pro to dynamic generation is faster prototyping if the underlying schema changes, since you can hot reload the server/client. But one key downside includes not being able to typehint anything during development or compilation. For production use compiling it down to static code is a must.
I've started using a pipeline that re-generates static compiled files and their typescript definitions automatically. Here's how to do it.
The standard protoc version that generates code for Go/Java/Python/etc. doesn't have support for generating javascript definition files.
JS generation is only supported through the grpc-tools library, which includes a wrapped version of protoc and a plugin to generate javascript code.1 The CLI interface is identical except now it offers javascript generation support.
So to get started you'll have to download grpc-tools and grpc_tools_node_protoc_ts as dependencies. The second dependency will support the typescript generation.
npm install -d grpc-tools grpc_tools_node_protoc_ts
The javascript-enabled protoc now lives within node modules, so to make sure it installed correctly you can call:
$ ./node_modules/.bin/grpc_tools_node_protoc --help
Now it's time to wire everything up. Start with generating the javascript code. The --js_out argument will generate the definition files for messages, enums, and the like. The --grpc_out will generate the stub files for client and server implementations. In most applications you'll need both. If bash is your speed:
build.sh:
(
mkdir -p app/src/api \\
&& app/node_modules/.bin/grpc_tools_node_protoc \\
--grpc_out=grpc_js:app/src/api \\
--js_out=import_style=commonjs,binary:app/src/api \\
protos/api.proto
)
To generate the typescript definitions:
build.sh:
(
protoc \\
--plugin=protoc-gen-ts=app/node_modules/.bin/protoc-gen-ts \\
--ts_out=grpc_js:app/src/api \\
protos/api.proto
)
At this point you should have a populated app/src/api/protos folder with all the definition files. To use in your main code, just import the appropriate classes and bask in the glow of your newfound typehints.
import { CommandMessage } from './api/protos/api_pb';
import { APIClient } from './api/protos/api_grpc_pb';
The one last step is to automate the rebuild process. I use chokidar to watch the protobuf directory and re-run this build script. I also add a final generation just for good measure before I build my typescript files down to javascript:
{
...
"scripts": {
"build": "./build.sh && tsc",
"watch-protobuf": "./watch.js"
}
}
Easy. And your dev workflow will thank you.
It should be possible to use the plugin directly with the standard protoc install through the --plugin keyword arg, but it didn't seem to work as of libprotoc 3.21.8. ↩
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。