Share
Embed
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.
Christian Münch
December 10, 2020
Transcript
29 slides
-
Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench
/ muench.dev 1 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 -
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 -
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 -
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 -
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 -
Reflection import ( "google.golang.org/grpc/reflection" // ... ) func main() {
// ... s := grpc.NewServer() pb.RegisterStockServer(s, &server{}) reflection.Register(s) // ... } 7 7 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
gRPC Web UI https://github.com/fullstorydev/grpcui 16 16 Christian Münch / @cmuench
/ muench.dev Christian Münch / @cmuench / muench.dev -
Christian Münch / @cmuench / muench.dev Christian Münch / @cmuench
/ muench.dev 18 18 -
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 -
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 -
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 -
<?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 -
<?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 -
PHP Setup 24 24 Christian Münch / @cmuench / muench.dev
Christian Münch / @cmuench / muench.dev -
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 -
https://github.com/spiral/php-grpc https://roadrunner.dev 26 26 Christian Münch / @cmuench / muench.dev
Christian Münch / @cmuench / muench.dev -
.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 -
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 -
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