gRPC

intro

Remote Procedure Call

RPC

// service1
export const sum = (a, b) => a + b;
// service2

import { sum } from 'service1';

console.log('result', sum(1, 2));

gRPC

Google Remote Procedure Call

service-to-service communication

Http2 + Protocol Buffers = gRPC

transport

message format

  • Code generation
  • High performance 
  • Strict specification
  • Cross platform/languages
  • Streaming
  • Deadline/timeouts and cancellation

Strengths

哦所以就是換個方式 call API ?

對捏

啊幹嘛還要學一個別的方式 call API ?

沒錯。但就跟 graphQL 一樣

它一定還是有點東西才會彰顯它的價值所在

長知識

What is proto ?

config file -> .proto

syntax = "proto3";

package songs; // name space

import "google/protobuf/empty.proto";

message Song {
  int32 id = 1;
  string title = 2;
  string artist = 3;
}

message Comment {
  int32 song_id = 1;
  string username = 2;
  string body = 3;
}

service Songs {
  rpc GetSong(google.protobuf.Empty) returns (Song) {};
  rpc AddSongs(stream Song) returns (google.protobuf.Empty) {};
  rpc GetChat(Song) returns (stream Comment) {};
  rpc LiveChat(stream Comment) returns (stream Comment) {};
}

define schema

syntax = "proto3";

package songs; // name space

import "google/protobuf/empty.proto";

message Song {
  int32 id = 1;
  string title = 2;
  string artist = 3;
}

message Comment {
  int32 song_id = 1;
  string username = 2;
  string body = 3;
}

service Songs {
  rpc GetSong(google.protobuf.Empty) returns (Song) {};
  rpc AddSongs(stream Song) returns (google.protobuf.Empty) {};
  rpc GetChat(Song) returns (stream Comment) {};
  rpc LiveChat(stream Comment) returns (stream Comment) {};
}

filed type

method type

config file -> .proto

// source: songs.proto
/**
 * @fileoverview
 * @enhanceable
 * @suppress {messageConventions} JS Compiler reports an error if a variable or
 *     field starts with 'MSG_' and isn't a translatable message.
 * @public
 */
// GENERATED CODE -- DO NOT EDIT!
/* eslint-disable */
// @ts-nocheck

var jspb = require('google-protobuf');
var goog = jspb;
var global = Function('return this')();

var google_protobuf_empty_pb = require('google-protobuf/google/protobuf/empty_pb.js');
goog.object.extend(proto, google_protobuf_empty_pb);
goog.exportSymbol('proto.songs.Comment', null, global);
goog.exportSymbol('proto.songs.Song', null, global);
/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.songs.Song = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.songs.Song, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.songs.Song.displayName = 'proto.songs.Song';
}

compile it 

code generation/cross platform

class SongsServer implements ISongsServer {
    getSong(call: grpc.ServerUnaryCall<Empty, Song>, callback: sendUnaryData<Song>): void {
        console.log(`${new Date().toISOString()}    getSong`);
        callback(null, getSong());
    }
    addSongs(call: grpc.ServerReadableStream<Song, Empty>, callback: sendUnaryData<Empty>): void {
        console.log(`${new Date().toISOString()}    addSongs`);
        call.on('data', (song: Song) => {
            addSong(song);
        });
        call.on('end', () => callback(null, new Empty()));
    }
....
const server = new grpc.Server();

server.addService(SongsService, new SongsServer());
server.bindAsync(`localhost:${process.env.PORT}`, 
   grpc.ServerCredentials.createInsecure(), (err, port) => {
       if (err) {
           throw err;
       }
      console.log(`Listening on ${port}`);
   server.start();
});

implement the server

DEMO

Restful vs graphQL vs gRPC

Usage scenarios

  • Efficiently connecting polyglot services in microservices style architecture
  • Connecting mobile devices, browser clients to backend services
  • Generating efficient client libraries

End

gRPC

By Jay Chou

gRPC

  • 369