| 
 | 1 | +# @grpc/grpc-js support  | 
 | 2 | + | 
 | 3 | +## Why  | 
 | 4 | +[@grpc/grpc-js](https://www.npmjs.com/package/@grpc/grpc-js) is a great project. it's pure js implementation, this makes it's easy to build docker images & cooperation with electron, etc.  | 
 | 5 | + | 
 | 6 | +Recently grpc-js has published it's `1.0.1` version, means it's **NO LONGER** `beta`. So it's a good time to support it.  | 
 | 7 | + | 
 | 8 | +## Some information  | 
 | 9 | + | 
 | 10 | +* grpc: [github](https://github.com/grpc/grpc-node/tree/master/packages/grpc-native-core) | [npm](https://www.npmjs.com/package/grpc)  | 
 | 11 | +* grpc-js: [github](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js) | [npm](https://www.npmjs.com/package/@grpc/grpc-js)  | 
 | 12 | +* [[question] How to generate `require('@grpc/grpc-js')` instead of `require('grpc')` #931](https://github.com/grpc/grpc-node/issues/931)  | 
 | 13 | +* [Add support for generate_package_definition #56](https://github.com/agreatfool/grpc_tools_node_protoc_ts/issues/56)  | 
 | 14 | + | 
 | 15 | +## Migrating from [grpc](https://www.npmjs.com/package/grpc) to [@grpc/grpc-js](https://www.npmjs.com/package/@grpc/grpc-js)  | 
 | 16 | +### Code generation  | 
 | 17 | +Want to use grpc-js, [grpc-tools](https://www.npmjs.com/package/grpc-tools) version `1.8.1` is **REQUIRED**.  | 
 | 18 | + | 
 | 19 | +Change your bash script from:  | 
 | 20 | + | 
 | 21 | +```bash  | 
 | 22 | +grpc_tools_node_protoc \  | 
 | 23 | +--js_out=import_style=commonjs,binary:./src/grpc/proto \  | 
 | 24 | +--grpc_out=./src/grpc/proto \  | 
 | 25 | +--plugin=protoc-gen-grpc=`which grpc_tools_node_protoc_plugin` \  | 
 | 26 | +-I ./proto \  | 
 | 27 | +proto/*.proto  | 
 | 28 | +```  | 
 | 29 | + | 
 | 30 | +to:  | 
 | 31 | + | 
 | 32 | +```bash  | 
 | 33 | +grpc_tools_node_protoc \  | 
 | 34 | +--js_out=import_style=commonjs,binary:./src/grpcjs/proto \  | 
 | 35 | +--grpc_out=generate_package_definition:./src/grpcjs/proto \  | 
 | 36 | +-I ./proto \  | 
 | 37 | +proto/*.proto  | 
 | 38 | +```  | 
 | 39 | + | 
 | 40 | +`--plugin` is no longer necessary and add `generate_package_definition` in `--grpc-out`.  | 
 | 41 | + | 
 | 42 | +There are two generated files:   | 
 | 43 | + | 
 | 44 | +* `*_pb.js`: Message codes have **NO** changes  | 
 | 45 | +* `*_grpc_pb.js`: Service codes have some changes  | 
 | 46 | + | 
 | 47 | +```js  | 
 | 48 | +- var grpc = require('grpc');  | 
 | 49 | + | 
 | 50 | +- var BookServiceService = exports.BookServiceService = {  | 
 | 51 | ++ var BookServiceService = exports['com.book.BookService'] = {  | 
 | 52 | + | 
 | 53 | +- exports.BookServiceClient = grpc.makeGenericClientConstructor(BookServiceService);  | 
 | 54 | +```  | 
 | 55 | +
  | 
 | 56 | +* `grpc` is no longer necessary   | 
 | 57 | +* exported service object has new name, a package name like: `com.book.BookService`  | 
 | 58 | +* client object is no longer generated, users have to make it by self  | 
 | 59 | +
  | 
 | 60 | +### Typings  | 
 | 61 | +grpc has it's official typings: [index.d.ts](https://github.com/grpc/grpc-node/blob/master/packages/grpc-native-core/index.d.ts). Also grpc-js has an official typings itself (it's not included in github's online source codes), it's in the dir `node_modules/@grpc/grpc-js/build/src/index.d.ts`, and online source codes may give some hint: [index.ts](https://github.com/grpc/grpc-node/blob/master/packages/grpc-js/src/index.ts).    | 
 | 62 | +
  | 
 | 63 | +There are several differences between them:  | 
 | 64 | +
  | 
 | 65 | +All the `call`s in grpc-js has both request & response definition: `grpc.ServerUnaryCall<GetBookRequest, Book>` while grpc only needs the request part: `grpc.ServerUnaryCall<GetBookRequest>`. This is the most big change.  | 
 | 66 | +
  | 
 | 67 | +And in version `1.0.1` grpc-js has two useful typings not exported in typings index, you need to manually import them:  | 
 | 68 | +
  | 
 | 69 | +```js  | 
 | 70 | +import {sendUnaryData} from "@grpc/grpc-js/build/src/server-call";  | 
 | 71 | +import {handleClientStreamingCall} from "@grpc/grpc-js/build/src/server-call";  | 
 | 72 | +```  | 
 | 73 | +
  | 
 | 74 | +I guess it shall be a bug, maybe would be fixed later.  | 
 | 75 | +
  | 
 | 76 | +### Usage  | 
 | 77 | +See full examples here:  | 
 | 78 | +
  | 
 | 79 | +* [server.ts](https://github.com/agreatfool/grpc_tools_node_protoc_ts/blob/master/examples/src/grpcjs/server.ts)  | 
 | 80 | +* [client.ts](https://github.com/agreatfool/grpc_tools_node_protoc_ts/blob/master/examples/src/grpcjs/client.ts)  | 
 | 81 | +
  | 
 | 82 | +Most changes:  | 
 | 83 | +
  | 
 | 84 | +**server.ts**  | 
 | 85 | +
  | 
 | 86 | +add services part:  | 
 | 87 | +
  | 
 | 88 | +```typescript  | 
 | 89 | +// grpc  | 
 | 90 | +import { BookServiceService, ... } from "./proto/book_grpc_pb";  | 
 | 91 | +server.addService(BookServiceService, new ServerImpl());  | 
 | 92 | + | 
 | 93 | +// =>  | 
 | 94 | + | 
 | 95 | +// grpc-js  | 
 | 96 | +import * as bookGrpcPb from "./proto/book_grpc_pb";  | 
 | 97 | +// @ts-ignore  | 
 | 98 | +server.addService(bookGrpcPb["com.book.BookService"], new ServerImpl());  | 
 | 99 | +```  | 
 | 100 | +
  | 
 | 101 | +Since service object in js file is now exported with name like: "com.book.BookService", it's no longer possible to be imported with sentence: `import { YourService } from "your_grpc_pb"`.  | 
 | 102 | +
  | 
 | 103 | +And `// @ts-ignore` is required, without this there would be compiling error: `Index signature is missing in type 'ServerImpl'.`. Some information could be found here: [Index signature is missing in type (only on interfaces, not on type alias) #15300](https://github.com/microsoft/TypeScript/issues/15300). Though it may be possible to be fixed by [some hack](https://github.com/microsoft/TypeScript/issues/15300#issuecomment-576211076), I just use comments to ignore it, since the implementation is correct.  | 
 | 104 | + | 
 | 105 | +start server part, changed to async:  | 
 | 106 | + | 
 | 107 | +```typescript  | 
 | 108 | +// grpc  | 
 | 109 | +server.bind("127.0.0.1:50051", grpc.ServerCredentials.createInsecure());  | 
 | 110 | +server.start();  | 
 | 111 | +
  | 
 | 112 | +// =>  | 
 | 113 | +
  | 
 | 114 | +// grpc-js  | 
 | 115 | +server.bindAsync("127.0.0.1:50051", grpc.ServerCredentials.createInsecure(), (err, port) => {  | 
 | 116 | +    if (err) {  | 
 | 117 | +        throw err;  | 
 | 118 | +    }  | 
 | 119 | +    server.start();  | 
 | 120 | +});  | 
 | 121 | +```  | 
 | 122 | + | 
 | 123 | +**client.ts**  | 
 | 124 | + | 
 | 125 | +client object changes:  | 
 | 126 | + | 
 | 127 | +```typescript  | 
 | 128 | +// grpc  | 
 | 129 | +import { BookServiceClient } from "./proto/book_grpc_pb";  | 
 | 130 | +const client = new BookServiceClient("127.0.0.1:50051", grpc.credentials.createInsecure());  | 
 | 131 | +
  | 
 | 132 | +// =>  | 
 | 133 | +
  | 
 | 134 | +// grpc-js  | 
 | 135 | +import * as bookGrpcPb from "./proto/book_grpc_pb";  | 
 | 136 | +const BookServiceClient = grpc.makeClientConstructor(bookGrpcPb["com.book.BookService"], "BookService");  | 
 | 137 | +const client = new BookServiceClient("127.0.0.1:50051", grpc.credentials.createInsecure());  | 
 | 138 | +```  | 
 | 139 | + | 
 | 140 | +Since client object is no longer created by grpc-tools code generation, it have to be generated by user codes.  | 
 | 141 | + | 
 | 142 | +## What [grpc_tools_node_protoc_ts](https://www.npmjs.com/package/grpc_tools_node_protoc_ts) changed   | 
 | 143 | +`d.ts` generating bash script change, from:  | 
 | 144 | + | 
 | 145 | +```bash  | 
 | 146 | +grpc_tools_node_protoc \  | 
 | 147 | +--plugin=protoc-gen-ts=../bin/protoc-gen-ts \  | 
 | 148 | +--ts_out=./src/grpc/proto \  | 
 | 149 | +-I ./proto \  | 
 | 150 | +proto/*.proto  | 
 | 151 | +```  | 
 | 152 | + | 
 | 153 | +to:  | 
 | 154 | + | 
 | 155 | +```bash  | 
 | 156 | +grpc_tools_node_protoc \  | 
 | 157 | +--plugin=protoc-gen-ts=../bin/protoc-gen-ts \  | 
 | 158 | +--ts_out=generate_package_definition:./src/grpcjs/proto \  | 
 | 159 | +-I ./proto \  | 
 | 160 | +proto/*.proto  | 
 | 161 | +```  | 
 | 162 | + | 
 | 163 | +Add `generate_package_definition` in `--ts-out`, be consistent with grpc-js.  | 
 | 164 | + | 
 | 165 | +There is no changes in `*_pb.d.ts`, and some changes in `*_grpc_pb.d.ts`:  | 
 | 166 | + | 
 | 167 | +```typescript  | 
 | 168 | +- import * as grpc from "grpc";  | 
 | 169 | +
  | 
 | 170 | ++ import * as grpc from "@grpc/grpc-js";  | 
 | 171 | ++ import {handleClientStreamingCall} from "@grpc/grpc-js/build/src/server-call";  | 
 | 172 | +
  | 
 | 173 | +export interface IBookServiceServer {  | 
 | 174 | +    getBook: grpc.handleUnaryCall<book_pb.GetBookRequest, book_pb.Book>;  | 
 | 175 | +    getBooksViaAuthor: grpc.handleServerStreamingCall<book_pb.GetBookViaAuthor, book_pb.Book>;  | 
 | 176 | +-    getGreatestBook: grpc.handleClientStreamingCall<book_pb.GetBookRequest, book_pb.Book>;  | 
 | 177 | ++    getGreatestBook: handleClientStreamingCall<book_pb.GetBookRequest, book_pb.Book>;  | 
 | 178 | +    getBooks: grpc.handleBidiStreamingCall<book_pb.GetBookRequest, book_pb.Book>;  | 
 | 179 | +}  | 
 | 180 | +```  | 
 | 181 | + | 
 | 182 | +That's all.  | 
 | 183 | +
  | 
 | 184 | +If you are still using grpc, just do nothing, new version would not affect existing users.  | 
0 commit comments