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

gRPC All The Things

gRPC All The Things

gRPC is a technology for developing services. It has a rich ecosystem of support, which lets you build high-performance backend services with efficient network communication which can be exposed via http/json and GraphQL.

Michael Hamrah

September 04, 2018
Tweet

More Decks by Michael Hamrah

Other Decks in Programming

Transcript

  1. Agenda 3 gRPC Overview Working with gRPC Http and Json

    Support Google Cloud Endpoints Kubernetes GraphQL https://github.com/mhamrah/grpc-example
  2. gRPC 6 IDL w/ Multi-Language Efficient Serialization Plugin w/ protoc

    Forwards/Backwards Compatible Self-Describing
  3. IDL FTW 7 service Todos { // GetTodo returns a

    list of ToDos rpc GetTodo (GetTodoRequest) returns (Todo) {} } message Todo { string id = 1; string title = 2; bool completed = 3; } message GetTodoRequest { string id = 1; } </>
  4. Gen’d Code .gitignored! 9 type TodosServer interface { // GetTodo

    returns a single todo based on an id GetTodo(context.Context, *GetTodoRequest) (*Todo, error) } func RegisterTodosServer( s *grpc.Server, srv TodosServer) { ... } </>
  5. Service Logic 10 type Server struct { storage Storage }

    func (s *Server) GetTodo( ctx context.Context, in *pb.GetTodoRequest ) (*pb.Todo, error) { return s.storage.Read(ctx, in.Id) } </> todos/server/todos.go
  6. Server Code 11 lis, err := net.Listen("tcp", fmt.Sprintf(":%d", 50051)) grpcServer

    := grpc.NewServer() pb.RegisterTodosServer( grpcServer, todos.NewServer( todos.MemoryStorage{} ) ) reflection.Register(grpcServer) grpcServer.Serve(lis) </> todos/server/cmd/main.go
  7. Client Code 12 conn, _ := grpc.Dial( cfg.GetString("backend"), grpc.WithInsecure()) defer

    conn.Close() client := pb.NewTodosClient(conn) resp, err := client.CreateTodo( context.Background(), &pb.CreateTodoRequest{ Todo: &pb.Todo {Title: "foo"} }) fmt.Println("%v", resp.id) </> todos/client/cmd/main.go
  8. # grpc_cli call todos:50051 \ todos.Todos.CreateTodo 'todo: { title:"foo" }'

    connecting to todos:50051 id: "01CPBT4FWY3SHPK55B355DKEZQ" title: "foo" Rpc succeeded with OK status
  9. 17

  10. $ docker run -v `pwd`:/defs \ namely/gen-grpc-gateway -f todos.proto -s

    Todos $ docker build -t todos-gateway gen/grpc-gateway rpc UpdateTodo (UpdateTodoRequest) returns (Todo ) { option (google.api.http) = { patch: "/todos/{todo.id}" body: "todo" }; } grpc-gateway gRPC HTTP Call
  11. # curl todos-gw/todos -d '{ "todo": { "title": "foo" }

    }' {"id":"01CPDF3X4E73J3FC6T8XVWVTE9"} # curl todos-gw/swagger.json { … }
  12. More IDL Fun todos.proto descriptor.proto 22 </> $ protoc -I

    . \ --descriptor_set_out=gen/api_descriptor.pb \ --include_source_info --include_imports todos.proto
  13. Yaml Config 23 $ gcloud endpoints services deploy \ gen/api_descriptor.pb

    \ gcp-endpoints/api_config.yaml </> type: google.api.Service config_version: 3 name: todos.endpoints.grpc-demo-1.cloud.goog title: Todos gRPC API apis: - name: todos.Todos usage: rules: - selector: "*" allow_unregistered_calls: true
  14. 25

  15. 26

  16. Stitching With Ingress 27 apiVersion: extensions/v1beta1 kind: Ingress metadata: name:

    app-ingress spec: rules: - http: paths: - path: /todos backend: serviceName: todos-server servicePort: 8080 - path: /users backend: serviceName: users-server servicePort: 8080 </>
  17. private static final GraphQLSchema SCHEMA = Guice.createInjector( new SchemaProviderModule(), new

    TodosClientModule(), new TodosSchemaModule()) .getInstance(Key.get(GraphQLSchema.class, Schema.class)); final class TodosSchemaModule extends SchemaModule { @Query("todo") Todo getTodo(GetTodoRequest request, TodosGrpc.TodosBlockingStub client) { return client.getTodo(request); } }