alexxfreitag / grpc-java-todo

Projeto de estudo com gRPC e Java.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

grpc-java-todo

Projeto criado com o objetivo de colocar em prática estudo de gRPC em Java.

  1. Execução
  2. Conceitos
    1. O que é gRPC?
    2. REST vs gRPC
    3. Protocol Buffers
    4. Service definition
  3. Demo

Execução

Nesse projeto existe um client e um server. Para simular uma chamada gRPC, é necessário utilizar o gradle para baixar as dependências e rodar a task generateProto, que irá compilar o conteúdo existente no .proto file e transformar em classes para serem implementadas em build/generated.

$ ./gradlew generateProto

Para rodar o server:

$ ./gradlew runServer

Para rodar o client que irá executar uma chamada teste:

$ ./gradlew runClient

Conceitos

O que é gRPC?

Trata-se de um framework RPC (Remote Procedure Call - Requisição e Resposta) que permite manter comunicações em formato streaming bidirecional, utilizando o HTTP/2. Por padrão, utiliza Protocol Buffers para fazer a serialização dos dados.

REST vs gRPC

REST gRPC
Texto/JSON Protocol Buffers
unidirecional bidirecional e assíncrono
alta latência baixa latência
sem contrato contrato definido (.proto)
sem suporte a streaming suporte a streaming
design pré-definido design é livre
bibliotecas de terceiros geração de código

Protocol Buffers

Para trabalhar com o protocol buffers é usado um arquivo .proto, que tem como objetivo definir as estruturas dos dados e seus respectivos serviços. A primeira coisa a ser informado num arquivo .proto é a sua versão, que costuma ser a 3.

syntax = "proto3";

A partir disso, é possível incluir algumas opções para a linguagem utilizada (Java, Go, etc...), como especificar pacotes, definir se vai ser gerado um ou vários arquivos, entre vários outros.

option java_package = "com.devfreitag";
option java_multiple_files=true;

O principal do arquivo são as message e os service, que definem qual vai ser o escopo a ser seguido.

Uma message consiste em ser o contrato de um objeto, onde é definido quais suas propriedades especificando tipo, nome e posição.

message Object {
  type propertyName = position;
}

Para utilizar as messages em uma chamada gRPC, é possível definir uma interface no arquivo, onde a mesma terá seu código gerado pelo compilador do protocol buffer. Por exemplo, se quisermos definir que teremos uma chamada gRPC que irá criar um novo Todo, é possível fazer algo como:

syntax = "proto3";

message Todo {
  string id = 1;
  string description = 2;
  bool done = 3;
}

message CreateTodoRequest {
  string description = 1;
}

service TodoService {
  rpc CreateTodo(CreateTodoRequest) returns (Todo) {}
}

Service definition

Quando definimos quais as interfaces do service que iremos implementar, pode ser especificado qual o tipo da requisição/resposta, sendo as opções:

  • Unary: uma chamada RPC normal, onde o cliente envia uma requisição para o servidor e aguarda uma resposta.

    rpc Method(Request) returns (Response) {}
  • Server streaming: cliente envia uma única requisição para o servidor e recebe a resposta do servidor em formato streaming, no qual o cliente irá ler até não haver mais mensagens.

    rpc Method(Request) returns (stream Response) {}
  • Client streaming: cliente envia uma sequência de mensagens para o servidor que, por sua vez, só vai processar e retornar a resposta quando o cliente terminar de enviar.

    rpc Method(stream Request) returns (ResponseList) {}
  • Bidirectional streaming: tanto o cliente quanto o servidor vão enviar suas mensagens em formato streaming, de forma independente.

    rpc Method(stream Request) returns (stream Response) {}

Demo

Abaixo, capturas de telas que demonstram de forma mais visual como é, na prática, feito as requisições gRPC. Foi utilizado o programa Postman como client.

  • Unary: Unary

  • Client Streaming: Client Streaming

  • Bidirectional Streaming: Bidirectional Streaming

About

Projeto de estudo com gRPC e Java.


Languages

Language:Java 100.0%