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.

Bc302e4bfb9e897e01293bb1c54996aa?s=128

Christian Münch

December 10, 2020
Tweet

More Decks by Christian Münch

Other Decks in Technology

Transcript

  1. Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench

    / muench.dev 1 1
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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
  7. Reflection import ( "google.golang.org/grpc/reflection" // ... ) func main() {

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

  9. 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
  10. 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
  11. 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
  12. 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
  13. 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
  14. 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
  15. 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
  16. gRPC Web UI https://github.com/fullstorydev/grpcui 16 16 Christian Münch / @cmuench

    / muench.dev Christian Münch / @cmuench / muench.dev
  17. 17 17

  18. Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench

    / muench.dev 18 18
  19. 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
  20. 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
  21. 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
  22. <?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
  23. <?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
  24. PHP Setup 24 24 Christian Münch / @cmuench / muench.dev

    Christian Münch / @cmuench / muench.dev
  25. 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
  26. https://github.com/spiral/php-grpc https://roadrunner.dev 26 26 Christian Münch / @cmuench / muench.dev

    Christian Münch / @cmuench / muench.dev
  27. .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
  28. 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
  29. Links https://grpc.io https://github.com/fullstorydev/grpcurl https://github.com/fullstorydev/grpcui https://www.yonego.com/nl/why-milliseconds-matter/ https://github.com/spiral/php-grpc 29 29 Christian Münch

    / @cmuench / muench.dev Christian Münch / @cmuench / muench.dev