├── .env.example ├── .github └── workflows │ └── nodejs.yml ├── .gitignore ├── README.md ├── client.js ├── package-lock.json ├── package.json └── proto └── chat.proto /.env.example: -------------------------------------------------------------------------------- 1 | RPC_HOST=localhost 2 | RPC_PORT=9000 -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Node.js CI 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | strategy: 18 | matrix: 19 | node-version: [10.x, 12.x] 20 | 21 | steps: 22 | - uses: actions/checkout@v2 23 | - name: Use Node.js ${{ matrix.node-version }} 24 | uses: actions/setup-node@v1 25 | with: 26 | node-version: ${{ matrix.node-version }} 27 | - run: npm ci 28 | - run: npm run build --if-present 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .env 3 | node_modules/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RPC Client in NodeJS 2 | 3 | ![hero](https://res.cloudinary.com/ichtrojan/image/upload/v1588771860/Screenshot_2020-05-06_at_14.29.28_bub5m3.png) 4 | 5 | ## Introduction 6 | 7 | This codebase was built as a demo to practice RPC with [Go](https://golang.org) and [Javascript (node)](http://nodejs.org). 8 | The RPC server was built in Go, you can find the codebase [here](https://github.com/ichtrojan/grpc-server). 9 | 10 | ## Prerequisites 11 | * Protobuf installed on you machine 12 | * NodeJS installed on your Machine 13 | * Basic understanding of the basics of RPC 14 | * Fundamental knowledge of NodeJS 15 | * Fundamental knowledge of Go (to set up the RPC server) 16 | 17 | ## Installation 18 | 19 | * clone this repo by running: 20 | 21 | ```bash 22 | git clone https://github.com/ichtrojan/node-rpc-client.git 23 | ``` 24 | 25 | * change directory into the repo: 26 | 27 | ```bash 28 | cd node-rpc-client 29 | ``` 30 | 31 | * Install dependencies: 32 | 33 | ```bash 34 | npm install 35 | ``` 36 | 37 | * Create `.env` frile from sample: 38 | 39 | ```bash 40 | cp .env.example .env 41 | ``` 42 | 43 | * Run the client 44 | 45 | ```bash 46 | node client.js 47 | ``` 48 | 49 | By default, the client will listen on `localhost` via port `9000`. which is what was duplicated from the `.env.example` file and also what is defined in the RPC server config assuming all configuration are left as default. 50 | 51 | ## Conclusion 52 | 53 | I would normally explain what every line does. But, I do not have the mental bandwidth to do so at the moment. 54 | You can take a look at the hero image at the top, my IDE did its best to explain what each parameter does. 55 | 56 | Regards
57 | Michael Trojan Okoh 58 | -------------------------------------------------------------------------------- /client.js: -------------------------------------------------------------------------------- 1 | const dotenv = require('dotenv') 2 | 3 | const GRPCClient = require('node-grpc-client') 4 | 5 | const path = require("path") 6 | 7 | const PROTO_PATH = path.resolve(__dirname, './proto/chat.proto') 8 | 9 | dotenv.config() 10 | 11 | const PORT = process.env.RPC_PORT 12 | const HOST = process.env.RPC_HOST 13 | 14 | const client = new GRPCClient(PROTO_PATH, 'chat', 'ChatService', `${HOST}:${PORT}`) 15 | 16 | const message = { 17 | body: "Hello from Trojan", 18 | } 19 | 20 | const details = { 21 | name: "Trojan", 22 | age: 40 23 | } 24 | 25 | client.runService('SayHello', message, (err, res) => { 26 | console.log(res.body); 27 | }); 28 | 29 | client.runService('GetDetails', details, (err, res) => { 30 | console.log(res.body); 31 | }); -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rpc-client", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@grpc/proto-loader": { 8 | "version": "0.5.4", 9 | "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.5.4.tgz", 10 | "integrity": "sha512-HTM4QpI9B2XFkPz7pjwMyMgZchJ93TVkL3kWPW8GDMDKYxsMnmf4w2TNMJK7+KNiYHS5cJrCEAFlF+AwtXWVPA==", 11 | "dev": true, 12 | "requires": { 13 | "lodash.camelcase": "^4.3.0", 14 | "protobufjs": "^6.8.6" 15 | }, 16 | "dependencies": { 17 | "long": { 18 | "version": "4.0.0", 19 | "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", 20 | "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", 21 | "dev": true 22 | }, 23 | "protobufjs": { 24 | "version": "6.9.0", 25 | "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.9.0.tgz", 26 | "integrity": "sha512-LlGVfEWDXoI/STstRDdZZKb/qusoAWUnmLg9R8OLSO473mBLWHowx8clbX5/+mKDEI+v7GzjoK9tRPZMMcoTrg==", 27 | "dev": true, 28 | "requires": { 29 | "@protobufjs/aspromise": "^1.1.2", 30 | "@protobufjs/base64": "^1.1.2", 31 | "@protobufjs/codegen": "^2.0.4", 32 | "@protobufjs/eventemitter": "^1.1.0", 33 | "@protobufjs/fetch": "^1.1.0", 34 | "@protobufjs/float": "^1.0.2", 35 | "@protobufjs/inquire": "^1.1.0", 36 | "@protobufjs/path": "^1.1.2", 37 | "@protobufjs/pool": "^1.1.0", 38 | "@protobufjs/utf8": "^1.1.0", 39 | "@types/long": "^4.0.1", 40 | "@types/node": "^13.7.0", 41 | "long": "^4.0.0" 42 | } 43 | } 44 | } 45 | }, 46 | "@protobufjs/aspromise": { 47 | "version": "1.1.2", 48 | "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", 49 | "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=", 50 | "dev": true 51 | }, 52 | "@protobufjs/base64": { 53 | "version": "1.1.2", 54 | "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", 55 | "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", 56 | "dev": true 57 | }, 58 | "@protobufjs/codegen": { 59 | "version": "2.0.4", 60 | "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", 61 | "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", 62 | "dev": true 63 | }, 64 | "@protobufjs/eventemitter": { 65 | "version": "1.1.0", 66 | "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", 67 | "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=", 68 | "dev": true 69 | }, 70 | "@protobufjs/fetch": { 71 | "version": "1.1.0", 72 | "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", 73 | "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", 74 | "dev": true, 75 | "requires": { 76 | "@protobufjs/aspromise": "^1.1.1", 77 | "@protobufjs/inquire": "^1.1.0" 78 | } 79 | }, 80 | "@protobufjs/float": { 81 | "version": "1.0.2", 82 | "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", 83 | "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=", 84 | "dev": true 85 | }, 86 | "@protobufjs/inquire": { 87 | "version": "1.1.0", 88 | "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", 89 | "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=", 90 | "dev": true 91 | }, 92 | "@protobufjs/path": { 93 | "version": "1.1.2", 94 | "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", 95 | "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=", 96 | "dev": true 97 | }, 98 | "@protobufjs/pool": { 99 | "version": "1.1.0", 100 | "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", 101 | "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=", 102 | "dev": true 103 | }, 104 | "@protobufjs/utf8": { 105 | "version": "1.1.0", 106 | "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", 107 | "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", 108 | "dev": true 109 | }, 110 | "@types/bytebuffer": { 111 | "version": "5.0.41", 112 | "resolved": "https://registry.npmjs.org/@types/bytebuffer/-/bytebuffer-5.0.41.tgz", 113 | "integrity": "sha512-Mdrv4YcaHvpkx25ksqqFaezktx3yZRcd51GZY0rY/9avyaqZdiT/GiWRhfrJhMpgzXqTOSHgGvsumGxJFNiZZA==", 114 | "dev": true, 115 | "requires": { 116 | "@types/long": "*", 117 | "@types/node": "*" 118 | } 119 | }, 120 | "@types/long": { 121 | "version": "4.0.1", 122 | "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", 123 | "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==", 124 | "dev": true 125 | }, 126 | "@types/node": { 127 | "version": "13.13.4", 128 | "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.4.tgz", 129 | "integrity": "sha512-x26ur3dSXgv5AwKS0lNfbjpCakGIduWU1DU91Zz58ONRWrIKGunmZBNv4P7N+e27sJkiGDsw/3fT4AtsqQBrBA==", 130 | "dev": true 131 | }, 132 | "ansi-regex": { 133 | "version": "2.1.1", 134 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 135 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", 136 | "dev": true 137 | }, 138 | "ascli": { 139 | "version": "1.0.1", 140 | "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz", 141 | "integrity": "sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=", 142 | "dev": true, 143 | "requires": { 144 | "colour": "~0.7.1", 145 | "optjs": "~3.2.2" 146 | } 147 | }, 148 | "balanced-match": { 149 | "version": "1.0.0", 150 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 151 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 152 | "dev": true 153 | }, 154 | "brace-expansion": { 155 | "version": "1.1.11", 156 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 157 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 158 | "dev": true, 159 | "requires": { 160 | "balanced-match": "^1.0.0", 161 | "concat-map": "0.0.1" 162 | } 163 | }, 164 | "bytebuffer": { 165 | "version": "5.0.1", 166 | "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", 167 | "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", 168 | "dev": true, 169 | "requires": { 170 | "long": "~3" 171 | } 172 | }, 173 | "camelcase": { 174 | "version": "2.1.1", 175 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", 176 | "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", 177 | "dev": true 178 | }, 179 | "cliui": { 180 | "version": "3.2.0", 181 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", 182 | "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", 183 | "dev": true, 184 | "requires": { 185 | "string-width": "^1.0.1", 186 | "strip-ansi": "^3.0.1", 187 | "wrap-ansi": "^2.0.0" 188 | } 189 | }, 190 | "code-point-at": { 191 | "version": "1.1.0", 192 | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", 193 | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", 194 | "dev": true 195 | }, 196 | "colour": { 197 | "version": "0.7.1", 198 | "resolved": "https://registry.npmjs.org/colour/-/colour-0.7.1.tgz", 199 | "integrity": "sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g=", 200 | "dev": true 201 | }, 202 | "concat-map": { 203 | "version": "0.0.1", 204 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 205 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 206 | "dev": true 207 | }, 208 | "decamelize": { 209 | "version": "1.2.0", 210 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 211 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", 212 | "dev": true 213 | }, 214 | "dotenv": { 215 | "version": "8.2.0", 216 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", 217 | "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==", 218 | "dev": true 219 | }, 220 | "fs.realpath": { 221 | "version": "1.0.0", 222 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 223 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 224 | "dev": true 225 | }, 226 | "glob": { 227 | "version": "7.1.6", 228 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 229 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 230 | "dev": true, 231 | "requires": { 232 | "fs.realpath": "^1.0.0", 233 | "inflight": "^1.0.4", 234 | "inherits": "2", 235 | "minimatch": "^3.0.4", 236 | "once": "^1.3.0", 237 | "path-is-absolute": "^1.0.0" 238 | } 239 | }, 240 | "grpc": { 241 | "version": "1.24.2", 242 | "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.24.2.tgz", 243 | "integrity": "sha512-EG3WH6AWMVvAiV15d+lr+K77HJ/KV/3FvMpjKjulXHbTwgDZkhkcWbwhxFAoTdxTkQvy0WFcO3Nog50QBbHZWw==", 244 | "dev": true, 245 | "requires": { 246 | "@types/bytebuffer": "^5.0.40", 247 | "lodash.camelcase": "^4.3.0", 248 | "lodash.clone": "^4.5.0", 249 | "nan": "^2.13.2", 250 | "node-pre-gyp": "^0.14.0", 251 | "protobufjs": "^5.0.3" 252 | }, 253 | "dependencies": { 254 | "abbrev": { 255 | "version": "1.1.1", 256 | "bundled": true, 257 | "dev": true 258 | }, 259 | "ansi-regex": { 260 | "version": "2.1.1", 261 | "bundled": true, 262 | "dev": true 263 | }, 264 | "aproba": { 265 | "version": "1.2.0", 266 | "bundled": true, 267 | "dev": true 268 | }, 269 | "are-we-there-yet": { 270 | "version": "1.1.5", 271 | "bundled": true, 272 | "dev": true, 273 | "requires": { 274 | "delegates": "^1.0.0", 275 | "readable-stream": "^2.0.6" 276 | } 277 | }, 278 | "balanced-match": { 279 | "version": "1.0.0", 280 | "bundled": true, 281 | "dev": true 282 | }, 283 | "brace-expansion": { 284 | "version": "1.1.11", 285 | "bundled": true, 286 | "dev": true, 287 | "requires": { 288 | "balanced-match": "^1.0.0", 289 | "concat-map": "0.0.1" 290 | } 291 | }, 292 | "chownr": { 293 | "version": "1.1.3", 294 | "bundled": true, 295 | "dev": true 296 | }, 297 | "code-point-at": { 298 | "version": "1.1.0", 299 | "bundled": true, 300 | "dev": true 301 | }, 302 | "concat-map": { 303 | "version": "0.0.1", 304 | "bundled": true, 305 | "dev": true 306 | }, 307 | "console-control-strings": { 308 | "version": "1.1.0", 309 | "bundled": true, 310 | "dev": true 311 | }, 312 | "core-util-is": { 313 | "version": "1.0.2", 314 | "bundled": true, 315 | "dev": true 316 | }, 317 | "debug": { 318 | "version": "3.2.6", 319 | "bundled": true, 320 | "dev": true, 321 | "requires": { 322 | "ms": "^2.1.1" 323 | } 324 | }, 325 | "deep-extend": { 326 | "version": "0.6.0", 327 | "bundled": true, 328 | "dev": true 329 | }, 330 | "delegates": { 331 | "version": "1.0.0", 332 | "bundled": true, 333 | "dev": true 334 | }, 335 | "detect-libc": { 336 | "version": "1.0.3", 337 | "bundled": true, 338 | "dev": true 339 | }, 340 | "fs-minipass": { 341 | "version": "1.2.7", 342 | "bundled": true, 343 | "dev": true, 344 | "requires": { 345 | "minipass": "^2.6.0" 346 | } 347 | }, 348 | "fs.realpath": { 349 | "version": "1.0.0", 350 | "bundled": true, 351 | "dev": true 352 | }, 353 | "gauge": { 354 | "version": "2.7.4", 355 | "bundled": true, 356 | "dev": true, 357 | "requires": { 358 | "aproba": "^1.0.3", 359 | "console-control-strings": "^1.0.0", 360 | "has-unicode": "^2.0.0", 361 | "object-assign": "^4.1.0", 362 | "signal-exit": "^3.0.0", 363 | "string-width": "^1.0.1", 364 | "strip-ansi": "^3.0.1", 365 | "wide-align": "^1.1.0" 366 | } 367 | }, 368 | "glob": { 369 | "version": "7.1.4", 370 | "bundled": true, 371 | "dev": true, 372 | "requires": { 373 | "fs.realpath": "^1.0.0", 374 | "inflight": "^1.0.4", 375 | "inherits": "2", 376 | "minimatch": "^3.0.4", 377 | "once": "^1.3.0", 378 | "path-is-absolute": "^1.0.0" 379 | } 380 | }, 381 | "has-unicode": { 382 | "version": "2.0.1", 383 | "bundled": true, 384 | "dev": true 385 | }, 386 | "iconv-lite": { 387 | "version": "0.4.24", 388 | "bundled": true, 389 | "dev": true, 390 | "requires": { 391 | "safer-buffer": ">= 2.1.2 < 3" 392 | } 393 | }, 394 | "ignore-walk": { 395 | "version": "3.0.3", 396 | "bundled": true, 397 | "dev": true, 398 | "requires": { 399 | "minimatch": "^3.0.4" 400 | } 401 | }, 402 | "inflight": { 403 | "version": "1.0.6", 404 | "bundled": true, 405 | "dev": true, 406 | "requires": { 407 | "once": "^1.3.0", 408 | "wrappy": "1" 409 | } 410 | }, 411 | "inherits": { 412 | "version": "2.0.4", 413 | "bundled": true, 414 | "dev": true 415 | }, 416 | "ini": { 417 | "version": "1.3.5", 418 | "bundled": true, 419 | "dev": true 420 | }, 421 | "is-fullwidth-code-point": { 422 | "version": "1.0.0", 423 | "bundled": true, 424 | "dev": true, 425 | "requires": { 426 | "number-is-nan": "^1.0.0" 427 | } 428 | }, 429 | "isarray": { 430 | "version": "1.0.0", 431 | "bundled": true, 432 | "dev": true 433 | }, 434 | "minimatch": { 435 | "version": "3.0.4", 436 | "bundled": true, 437 | "dev": true, 438 | "requires": { 439 | "brace-expansion": "^1.1.7" 440 | } 441 | }, 442 | "minimist": { 443 | "version": "1.2.0", 444 | "bundled": true, 445 | "dev": true 446 | }, 447 | "minipass": { 448 | "version": "2.9.0", 449 | "bundled": true, 450 | "dev": true, 451 | "requires": { 452 | "safe-buffer": "^5.1.2", 453 | "yallist": "^3.0.0" 454 | } 455 | }, 456 | "minizlib": { 457 | "version": "1.3.3", 458 | "bundled": true, 459 | "dev": true, 460 | "requires": { 461 | "minipass": "^2.9.0" 462 | } 463 | }, 464 | "mkdirp": { 465 | "version": "0.5.1", 466 | "bundled": true, 467 | "dev": true, 468 | "requires": { 469 | "minimist": "0.0.8" 470 | }, 471 | "dependencies": { 472 | "minimist": { 473 | "version": "0.0.8", 474 | "bundled": true, 475 | "dev": true 476 | } 477 | } 478 | }, 479 | "ms": { 480 | "version": "2.1.2", 481 | "bundled": true, 482 | "dev": true 483 | }, 484 | "needle": { 485 | "version": "2.4.0", 486 | "bundled": true, 487 | "dev": true, 488 | "requires": { 489 | "debug": "^3.2.6", 490 | "iconv-lite": "^0.4.4", 491 | "sax": "^1.2.4" 492 | } 493 | }, 494 | "node-pre-gyp": { 495 | "version": "0.14.0", 496 | "bundled": true, 497 | "dev": true, 498 | "requires": { 499 | "detect-libc": "^1.0.2", 500 | "mkdirp": "^0.5.1", 501 | "needle": "^2.2.1", 502 | "nopt": "^4.0.1", 503 | "npm-packlist": "^1.1.6", 504 | "npmlog": "^4.0.2", 505 | "rc": "^1.2.7", 506 | "rimraf": "^2.6.1", 507 | "semver": "^5.3.0", 508 | "tar": "^4.4.2" 509 | } 510 | }, 511 | "nopt": { 512 | "version": "4.0.1", 513 | "bundled": true, 514 | "dev": true, 515 | "requires": { 516 | "abbrev": "1", 517 | "osenv": "^0.1.4" 518 | } 519 | }, 520 | "npm-bundled": { 521 | "version": "1.0.6", 522 | "bundled": true, 523 | "dev": true 524 | }, 525 | "npm-packlist": { 526 | "version": "1.4.6", 527 | "bundled": true, 528 | "dev": true, 529 | "requires": { 530 | "ignore-walk": "^3.0.1", 531 | "npm-bundled": "^1.0.1" 532 | } 533 | }, 534 | "npmlog": { 535 | "version": "4.1.2", 536 | "bundled": true, 537 | "dev": true, 538 | "requires": { 539 | "are-we-there-yet": "~1.1.2", 540 | "console-control-strings": "~1.1.0", 541 | "gauge": "~2.7.3", 542 | "set-blocking": "~2.0.0" 543 | } 544 | }, 545 | "number-is-nan": { 546 | "version": "1.0.1", 547 | "bundled": true, 548 | "dev": true 549 | }, 550 | "object-assign": { 551 | "version": "4.1.1", 552 | "bundled": true, 553 | "dev": true 554 | }, 555 | "once": { 556 | "version": "1.4.0", 557 | "bundled": true, 558 | "dev": true, 559 | "requires": { 560 | "wrappy": "1" 561 | } 562 | }, 563 | "os-homedir": { 564 | "version": "1.0.2", 565 | "bundled": true, 566 | "dev": true 567 | }, 568 | "os-tmpdir": { 569 | "version": "1.0.2", 570 | "bundled": true, 571 | "dev": true 572 | }, 573 | "osenv": { 574 | "version": "0.1.5", 575 | "bundled": true, 576 | "dev": true, 577 | "requires": { 578 | "os-homedir": "^1.0.0", 579 | "os-tmpdir": "^1.0.0" 580 | } 581 | }, 582 | "path-is-absolute": { 583 | "version": "1.0.1", 584 | "bundled": true, 585 | "dev": true 586 | }, 587 | "process-nextick-args": { 588 | "version": "2.0.1", 589 | "bundled": true, 590 | "dev": true 591 | }, 592 | "rc": { 593 | "version": "1.2.8", 594 | "bundled": true, 595 | "dev": true, 596 | "requires": { 597 | "deep-extend": "^0.6.0", 598 | "ini": "~1.3.0", 599 | "minimist": "^1.2.0", 600 | "strip-json-comments": "~2.0.1" 601 | } 602 | }, 603 | "readable-stream": { 604 | "version": "2.3.6", 605 | "bundled": true, 606 | "dev": true, 607 | "requires": { 608 | "core-util-is": "~1.0.0", 609 | "inherits": "~2.0.3", 610 | "isarray": "~1.0.0", 611 | "process-nextick-args": "~2.0.0", 612 | "safe-buffer": "~5.1.1", 613 | "string_decoder": "~1.1.1", 614 | "util-deprecate": "~1.0.1" 615 | } 616 | }, 617 | "rimraf": { 618 | "version": "2.7.1", 619 | "bundled": true, 620 | "dev": true, 621 | "requires": { 622 | "glob": "^7.1.3" 623 | } 624 | }, 625 | "safe-buffer": { 626 | "version": "5.1.2", 627 | "bundled": true, 628 | "dev": true 629 | }, 630 | "safer-buffer": { 631 | "version": "2.1.2", 632 | "bundled": true, 633 | "dev": true 634 | }, 635 | "sax": { 636 | "version": "1.2.4", 637 | "bundled": true, 638 | "dev": true 639 | }, 640 | "semver": { 641 | "version": "5.7.1", 642 | "bundled": true, 643 | "dev": true 644 | }, 645 | "set-blocking": { 646 | "version": "2.0.0", 647 | "bundled": true, 648 | "dev": true 649 | }, 650 | "signal-exit": { 651 | "version": "3.0.2", 652 | "bundled": true, 653 | "dev": true 654 | }, 655 | "string-width": { 656 | "version": "1.0.2", 657 | "bundled": true, 658 | "dev": true, 659 | "requires": { 660 | "code-point-at": "^1.0.0", 661 | "is-fullwidth-code-point": "^1.0.0", 662 | "strip-ansi": "^3.0.0" 663 | } 664 | }, 665 | "string_decoder": { 666 | "version": "1.1.1", 667 | "bundled": true, 668 | "dev": true, 669 | "requires": { 670 | "safe-buffer": "~5.1.0" 671 | } 672 | }, 673 | "strip-ansi": { 674 | "version": "3.0.1", 675 | "bundled": true, 676 | "dev": true, 677 | "requires": { 678 | "ansi-regex": "^2.0.0" 679 | } 680 | }, 681 | "strip-json-comments": { 682 | "version": "2.0.1", 683 | "bundled": true, 684 | "dev": true 685 | }, 686 | "tar": { 687 | "version": "4.4.13", 688 | "bundled": true, 689 | "dev": true, 690 | "requires": { 691 | "chownr": "^1.1.1", 692 | "fs-minipass": "^1.2.5", 693 | "minipass": "^2.8.6", 694 | "minizlib": "^1.2.1", 695 | "mkdirp": "^0.5.0", 696 | "safe-buffer": "^5.1.2", 697 | "yallist": "^3.0.3" 698 | } 699 | }, 700 | "util-deprecate": { 701 | "version": "1.0.2", 702 | "bundled": true, 703 | "dev": true 704 | }, 705 | "wide-align": { 706 | "version": "1.1.3", 707 | "bundled": true, 708 | "dev": true, 709 | "requires": { 710 | "string-width": "^1.0.2 || 2" 711 | } 712 | }, 713 | "wrappy": { 714 | "version": "1.0.2", 715 | "bundled": true, 716 | "dev": true 717 | }, 718 | "yallist": { 719 | "version": "3.1.1", 720 | "bundled": true, 721 | "dev": true 722 | } 723 | } 724 | }, 725 | "inflight": { 726 | "version": "1.0.6", 727 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 728 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 729 | "dev": true, 730 | "requires": { 731 | "once": "^1.3.0", 732 | "wrappy": "1" 733 | } 734 | }, 735 | "inherits": { 736 | "version": "2.0.4", 737 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 738 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 739 | "dev": true 740 | }, 741 | "invert-kv": { 742 | "version": "1.0.0", 743 | "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", 744 | "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", 745 | "dev": true 746 | }, 747 | "is-fullwidth-code-point": { 748 | "version": "1.0.0", 749 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", 750 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", 751 | "dev": true, 752 | "requires": { 753 | "number-is-nan": "^1.0.0" 754 | } 755 | }, 756 | "lcid": { 757 | "version": "1.0.0", 758 | "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", 759 | "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", 760 | "dev": true, 761 | "requires": { 762 | "invert-kv": "^1.0.0" 763 | } 764 | }, 765 | "lodash.camelcase": { 766 | "version": "4.3.0", 767 | "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", 768 | "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", 769 | "dev": true 770 | }, 771 | "lodash.clone": { 772 | "version": "4.5.0", 773 | "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", 774 | "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=", 775 | "dev": true 776 | }, 777 | "long": { 778 | "version": "3.2.0", 779 | "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", 780 | "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=", 781 | "dev": true 782 | }, 783 | "minimatch": { 784 | "version": "3.0.4", 785 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 786 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 787 | "dev": true, 788 | "requires": { 789 | "brace-expansion": "^1.1.7" 790 | } 791 | }, 792 | "nan": { 793 | "version": "2.14.1", 794 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", 795 | "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", 796 | "dev": true 797 | }, 798 | "node-grpc-client": { 799 | "version": "1.4.0", 800 | "resolved": "https://registry.npmjs.org/node-grpc-client/-/node-grpc-client-1.4.0.tgz", 801 | "integrity": "sha512-jBjdfDMK2zQBhf5/yYzrXPzmpvMuOIaPDlXGpKg280ny+aBMHVnzyFwgi5cQ9iH3XktnAlQOBOqdVaz1Eekc2w==", 802 | "dev": true, 803 | "requires": { 804 | "@grpc/proto-loader": "^0.5.3", 805 | "grpc": "^1.24.2" 806 | } 807 | }, 808 | "number-is-nan": { 809 | "version": "1.0.1", 810 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 811 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", 812 | "dev": true 813 | }, 814 | "once": { 815 | "version": "1.4.0", 816 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 817 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 818 | "dev": true, 819 | "requires": { 820 | "wrappy": "1" 821 | } 822 | }, 823 | "optjs": { 824 | "version": "3.2.2", 825 | "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz", 826 | "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4=", 827 | "dev": true 828 | }, 829 | "os-locale": { 830 | "version": "1.4.0", 831 | "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", 832 | "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", 833 | "dev": true, 834 | "requires": { 835 | "lcid": "^1.0.0" 836 | } 837 | }, 838 | "path-is-absolute": { 839 | "version": "1.0.1", 840 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 841 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 842 | "dev": true 843 | }, 844 | "protobufjs": { 845 | "version": "5.0.3", 846 | "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.3.tgz", 847 | "integrity": "sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA==", 848 | "dev": true, 849 | "requires": { 850 | "ascli": "~1", 851 | "bytebuffer": "~5", 852 | "glob": "^7.0.5", 853 | "yargs": "^3.10.0" 854 | } 855 | }, 856 | "string-width": { 857 | "version": "1.0.2", 858 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", 859 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", 860 | "dev": true, 861 | "requires": { 862 | "code-point-at": "^1.0.0", 863 | "is-fullwidth-code-point": "^1.0.0", 864 | "strip-ansi": "^3.0.0" 865 | } 866 | }, 867 | "strip-ansi": { 868 | "version": "3.0.1", 869 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 870 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 871 | "dev": true, 872 | "requires": { 873 | "ansi-regex": "^2.0.0" 874 | } 875 | }, 876 | "window-size": { 877 | "version": "0.1.4", 878 | "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", 879 | "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=", 880 | "dev": true 881 | }, 882 | "wrap-ansi": { 883 | "version": "2.1.0", 884 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", 885 | "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", 886 | "dev": true, 887 | "requires": { 888 | "string-width": "^1.0.1", 889 | "strip-ansi": "^3.0.1" 890 | } 891 | }, 892 | "wrappy": { 893 | "version": "1.0.2", 894 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 895 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 896 | "dev": true 897 | }, 898 | "y18n": { 899 | "version": "3.2.1", 900 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", 901 | "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", 902 | "dev": true 903 | }, 904 | "yargs": { 905 | "version": "3.32.0", 906 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", 907 | "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", 908 | "dev": true, 909 | "requires": { 910 | "camelcase": "^2.0.1", 911 | "cliui": "^3.0.3", 912 | "decamelize": "^1.1.1", 913 | "os-locale": "^1.4.0", 914 | "string-width": "^1.0.1", 915 | "window-size": "^0.1.4", 916 | "y18n": "^3.2.0" 917 | } 918 | } 919 | } 920 | } 921 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rpc-client", 3 | "version": "1.0.0", 4 | "description": "A RPC client to call a gRPC server ", 5 | "main": "client.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/ichtrojan/node-rpc-client.git" 12 | }, 13 | "author": "Michael Okoh", 14 | "license": "MIT", 15 | "bugs": { 16 | "url": "https://github.com/ichtrojan/node-rpc-client/issues" 17 | }, 18 | "homepage": "https://github.com/ichtrojan/node-rpc-client#readme", 19 | "devDependencies": { 20 | "dotenv": "^8.2.0", 21 | "grpc": "^1.24.2", 22 | "node-grpc-client": "^1.4.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /proto/chat.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package chat; 4 | 5 | message Message { 6 | string body = 1; 7 | } 8 | 9 | message Details { 10 | string name = 1; 11 | int32 age = 2; 12 | } 13 | 14 | message Response { 15 | string body = 1; 16 | } 17 | 18 | service ChatService { 19 | rpc SayHello(Message) returns (Response) {} 20 | rpc GetDetails(Details) returns (Response) {} 21 | } --------------------------------------------------------------------------------