Upgrade to Pro — share decks privately, control downloads, hide ads and more …

gRPC

 gRPC

Ho to use gRPC with code examples in golang and PHP.
The slides contain code of an example project which demostrates the transfer of stock data in e-commerce solution.
We generated a PHP Client Library which can communicate with the gRPC server.

Avatar for Christian Münch

Christian Münch

December 10, 2020
Tweet

More Decks by Christian Münch

Other Decks in Technology

Transcript

  1. Protocol Buffer syntax = "proto3"; service Stock { rpc Update(StockUpdateRequest)

    returns (StockUpdateResponse) {} } message StockUpdateRequest { string source_code = 1; string sku = 2; float qty = 3; } message StockUpdateResponse { bool ack = 1; } 2 2 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev
  2. Language specific settings used for client generation package stock; option

    go_package="git.muench.dev/grpc-demo/protos"; option php_namespace="MuenchDev\\GrpcDemo"; 3 3 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev
  3. Library Code Generator get github.com/golang/protobuf/protoc-gen-go 4 4 Christian Münch /

    @cmuench / muench.dev Christian Münch / @cmuench / muench.dev
  4. Go Code protoc \ --go_out=. \ --go_opt=paths=source_relative \ --go-grpc_out=. \

    --go-grpc_opt=paths=source_relative \ protos/stock.proto 5 5 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev
  5. type StockClient interface { Update(ctx context.Context, in *StockUpdateRequest, opts ...grpc.CallOption)

    (*StockUpdateResp } type stockClient struct { cc grpc.ClientConnInterface } func NewStockClient(cc grpc.ClientConnInterface) StockClient { return &stockClient{cc} } func (c *stockClient) Update(ctx context.Context, in *StockUpdateRequest, opts ...grpc.CallOption) (*StockUpdateResponse, error) { out := new(StockUpdateResponse) err := c.cc.Invoke(ctx, "/stock.Stock/Update", in, out, opts...) if err != nil { return nil, err } return out, nil } 6 6
  6. Reflection import ( "google.golang.org/grpc/reflection" // ... ) func main() {

    // ... s := grpc.NewServer() pb.RegisterStockServer(s, &server{}) reflection.Register(s) // ... } 7 7
  7. 8 8

  8. grpcurl # Mac users brew install grpcurl # GO devs

    do this ... go get github.com/fullstorydev/grpcurl/... go install github.com/fullstorydev/grpcurl/cmd/grpcurl 9 9 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev
  9. With reflection $> grpcurl -plaintext localhost:9000 list grpc.reflection.v1alpha.ServerReflection stock.Stock 10

    10 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev
  10. Without reflection $> grpcurl -plaintext \ -import-path=protos -proto=stock.proto \ localhost:9000

    list stock.Stock 11 11 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev
  11. Describe service $> grpcurl -plaintext localhost:9000 describe stock.Stock stock.Stock is

    a service: service Stock { rpc Update ( .stock.StockUpdateRequest ) returns ( .stock.StockUpdateResponse ); } 12 12 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev
  12. Describe message grpcurl -plaintext localhost:9000 describe stock.StockUpdateRequest stock.StockUpdateRequest is a

    message: message StockUpdateRequest { string source_code = 1; string sku = 2; float qty = 3; } 13 13 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev
  13. Message Templates grpcurl -plaintext -msg-template localhost:9000 describe stock.StockUpdateRequest stock.StockUpdateRequest is

    a message: message StockUpdateRequest { string source_code = 1; string sku = 2; float qty = 3; } Message template: { "sourceCode": "", "sku": "", "qty": 0 } 14 14
  14. CURL like post ... $> grpcurl -plaintext -d '{ "sourceCode":

    "default", "sku": "24-MB01", "qty": 1000.0 } ' localhost:9000 stock.Stock.Update { "ack": true } 15 15 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev
  15. gRPC Web UI https://github.com/fullstorydev/grpcui 16 16 Christian Münch / @cmuench

    / muench.dev Christian Münch / @cmuench / muench.dev
  16. PHP Code protoc --php_out=. \ --grpc_out=source_relative \ --plugin=protoc-gen-grpc=bins/opt/grpc_php_plugin \ protos/stock.proto

    19 19 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev
  17. git clone -b v1.32.0 https://github.com/grpc/grpc cd grpc && git submodule

    update --init && make grpc_php_plugin 20 20 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev
  18. Generated files . ├── GPBMetadata │ └── Protos │ └──

    Stock.php └── Stock ├── StockClient.php ├── StockUpdateRequest.php └── StockUpdateResponse.php 21 21 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev
  19. <?php namespace Stock; class StockClient extends \Grpc\BaseStub { /** *

    @param \Stock\StockUpdateRequest $argument input argument * @param array $metadata metadata * @param array $options call options * @return \Grpc\UnaryCall */ public function Update(\Stock\StockUpdateRequest $argument, $metadata = [], $options = []) { return $this->_simpleRequest('/stock.Stock/Update', $argument, ['\Stock\StockUpdateResponse', 'decode'], $metadata, $options); } } 22 22 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev
  20. <?php require 'vendor/autoload.php'; $client = new MuenchDev\GrpcDemo\StockClient( 'host.docker.internal:9000', ['credentials' =>

    Grpc\ChannelCredentials::createInsecure()], ); $unaryCall = $client->Update( (new \MuenchDev\GrpcDemo\StockUpdateRequest\StockUpdateRequest()) ->setQty((float) mt_rand(0, 1000)) ->setSku('24-MB01') ->setSourceCode('default') ); echo $unaryCall->getPeer(); $response = $unaryCall->wait(); echo sprintf("ACK: %b\n", $response[0]->getAck()); 23 23
  21. PHP Setup 24 24 Christian Münch / @cmuench / muench.dev

    Christian Münch / @cmuench / muench.dev
  22. ddev Setup ARG BASE_IMAGE FROM $BASE_IMAGE ENV PHP_VERSION=7.4 RUN \

    apt-get update && apt-get install -y libz-dev php-dev php-pear && \ pecl install grpc && \ pecl install protobuf && \ echo "extension=grpc.so" > /etc/php/7.4/cli/conf.d/grpc.ini && \ echo "extension=protobuf.so" > /etc/php/7.4/cli/conf.d/protobuf.ini echo "extension=grpc.so" > /etc/php/7.4/fpm/conf.d/grpc.ini && \ echo "extension=protobuf.so" > /etc/php/7.4/fpm/conf.d/protobuf.ini 25 25 Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev
  23. .rr.yaml config: grpc: listen: "tcp://:9001" proto: "service.proto" tls: key: "server.key"

    cert: "server.crt" workers: command: "php worker.php" pool: numWorkers: 4 run $ rr-grpc serve -v -d 27 27
  24. Sample GRPC PHP server. <?php use Spiral\Goridge; use Spiral\RoadRunner; ini_set('display_errors',

    'stderr'); require "vendor/autoload.php"; $server->registerService( \Service\EchoInterface::class, new EchoService() ); $w = new RoadRunner\Worker(new Goridge\StreamRelay(STDIN, STDOUT)); $server->serve($w); 28 28