1. Visão geral
gRPC é um framework e um conjunto de ferramentas de chamada de procedimento remoto (RPC) e linguagem neutras de plataformas desenvolvidas no Google. Ele permite que você defina um serviço usando buffers de protocolo, um conjunto de ferramentas e uma linguagem de serialização binária particularmente avançados. Em seguida, ele permite gerar stubs idiomáticos de clientes e servidores a partir da definição do serviço em várias linguagens.
Neste codelab, você aprenderá a criar um serviço baseado em Java que expõe uma API usando o framework gRPC e, em seguida, aprenderá a criar um cliente para usar o stub do gRPC gerado no lado do cliente.
O que você vai aprender
- A linguagem do buffer de protocolo
- Como implementar um serviço gRPC usando Java
- Como implementar um cliente gRPC usando Java.
Como você vai usar este tutorial?
Como você classificaria sua experiência com a criação de apps Node.js?
Como você classificaria sua experiência com a criação de apps Go?
2. Configuração e requisitos
Configuração de ambiente autoguiada
- Faça login no console do Cloud e crie um novo projeto ou reutilize um existente. Crie uma conta do Gmail ou do Google Workspace, se ainda não tiver uma.



Lembre-se do código do projeto, um nome exclusivo em todos os projetos do Google Cloud. O nome acima já foi escolhido e não servirá para você. Faremos referência a ele mais adiante neste codelab como PROJECT_ID.
- Em seguida, será necessário ativar o faturamento no Console do Cloud para usar os recursos do Google Cloud.
A execução deste codelab não será muito cara, se for o caso. Siga todas as instruções na seção "Limpeza", que orienta você sobre como encerrar recursos para não incorrer em cobranças além deste tutorial. Novos usuários do Google Cloud estão qualificados para o programa de US$300 de avaliação sem custo financeiro.
Google Cloud Shell
Embora este codelab possa ser operado no seu computador, aqui vamos usar o Google Cloud Shell, um ambiente de linha de comando executado no Cloud.
O Cloud Shell é uma máquina virtual com base em Debian que contém todas as ferramentas de desenvolvimento necessárias. Ela oferece um diretório principal persistente de 5 GB, além de ser executada no Google Cloud. Isso aprimora o desempenho e a autenticação da rede. Isso significa que tudo que você precisa para este codelab é um navegador (sim, funciona em um Chromebook).
- Para ativar o Cloud Shell no Console do Cloud, basta clicar em Ativar o Cloud Shell
. Leva apenas alguns instantes para provisionar e se conectar ao ambiente.


Depois de se conectar ao Cloud Shell, você já estará autenticado e o projeto estará configurado com seu PROJECT_ID.
gcloud auth list
Resposta ao comando
Credentialed accounts: - <myaccount>@<mydomain>.com (active)
gcloud config list project
Resposta ao comando
[core] project = <PROJECT_ID>
Se, por algum motivo, o projeto não estiver definido, basta emitir o seguinte comando:
gcloud config set project <PROJECT_ID>
Quer encontrar seu PROJECT_ID? Veja qual ID você usou nas etapas de configuração ou procure-o no painel do Console do Cloud:

O Cloud Shell também define algumas variáveis de ambiente por padrão, o que pode ser útil ao executar comandos futuros.
echo $GOOGLE_CLOUD_PROJECT
Resposta ao comando
<PROJECT_ID>
- Defina a zona padrão e a configuração do projeto:
gcloud config set compute/zone us-central1-f
É possível escolher uma variedade de zonas diferentes. Para mais informações, consulte Regiões e zonas.
3. Criar um serviço gRPC
Crie um novo projeto Java com o Maven:
$ mvn archetype:generate -DgroupId=com.example.grpc \ -DartifactId=grpc-hello-server \ -DarchetypeArtifactId=maven-archetype-quickstart \ -DinteractiveMode=false $ cd grpc-hello-server
Adicionar um arquivo de definição de gRPC
No gRPC, os payloads de serviço (solicitação e resposta) e as operações de serviço precisam ser capturados em uma IDL (linguagem de definição de interface). O gRPC usa a sintaxe do Protobuffer 3 para definir operações e payloads de mensagens. Vamos criar um arquivo proto para um serviço de saudação simples com uma solicitação "Hello" e uma resposta "hello".
Primeiro, crie um novo diretório proto para armazenar o novo arquivo proto:
$ mkdir -p src/main/proto
Em seguida, crie um novo arquivo proto src/main/proto/GreetingService.proto.
É possível usar vim,nano, ou emacs para editar o arquivo:
src/main/proto/GreetingService.proto
syntax = "proto3";
package com.example.grpc;
// Request payload
message HelloRequest {
// Each message attribute is strongly typed.
// You also must assign a "tag" number.
// Each tag number is unique within the message.
string name = 1;
// This defines a strongly typed list of String
repeated string hobbies = 2;
// There are many more basics types, like Enum, Map
// See https://developers.google.com/protocol-buffers/docs/proto3
// for more information.
}
message HelloResponse {
string greeting = 1;
}
// Defining a Service, a Service can have multiple RPC operations
service GreetingService {
// Define a RPC operation
rpc greeting(HelloRequest) returns (HelloResponse);
}
Adicionar o plug-in e as dependências do gRPC
Assim que você tiver a definição, podemos gerar o stub do lado do servidor e do cliente com esse arquivo. Você precisará adicionar as dependências e os plug-ins do gRPC.
Primeiro, adicione as dependências do gRPC ao pom.xml:
pom.xml
<project>
...
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.24.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.24.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.24.0</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
...
</dependencies>
...
</project>
Em seguida, adicione o plug-in:
pom.xml
<project>
...
<dependencies>
...
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.2</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.9.0:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.24.0:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Gerar os stubs
Quando você cria o aplicativo, o plug-in converte as definições proto em código Java.
$ mvn -DskipTests package
Para ver os arquivos gerados:
$ find target/generated-sources
Implementar o serviço
Primeiro, crie uma nova classe GreetingServiceImpl que implementará a operação greeting:
src/main/java/com/example/grpc/GreetingServiceImpl.java
package com.example.grpc;
import io.grpc.stub.StreamObserver;
public class GreetingServiceImpl extends GreetingServiceGrpc.GreetingServiceImplBase {
@Override
public void greeting(GreetingServiceOuterClass.HelloRequest request,
StreamObserver<GreetingServiceOuterClass.HelloResponse> responseObserver) {
// HelloRequest has toString auto-generated.
System.out.println(request);
// You must use a builder to construct a new Protobuffer object
GreetingServiceOuterClass.HelloResponse response = GreetingServiceOuterClass.HelloResponse.newBuilder()
.setGreeting("Hello there, " + request.getName())
.build();
// Use responseObserver to send a single response back
responseObserver.onNext(response);
// When you are done, you must call onCompleted.
responseObserver.onCompleted();
}
}
Implementar o servidor
Por fim, inicie um servidor para detectar em uma porta e registrar a implementação desse serviço. Edite a classe App e o método principal dela:
src/main/java/com/example/grpc/App.java
package com.example.grpc;
import io.grpc.*;
public class App
{
public static void main( String[] args ) throws Exception
{
// Create a new server to listen on port 8080
Server server = ServerBuilder.forPort(8080)
.addService(new GreetingServiceImpl())
.build();
// Start the server
server.start();
// Server threads are running in the background.
System.out.println("Server started");
// Don't exit the main thread. Wait until server is terminated.
server.awaitTermination();
}
}
Por fim, execute o servidor:
$ mvn -DskipTests package exec:java -Dexec.mainClass=com.example.grpc.App ... Server Started
4. Como consumir o serviço
O gerador já gerou todos os stubs do lado do cliente. Para simplificar o laboratório, vamos usar o mesmo projeto Maven, mas basta adicionar uma nova classe Client com um novo método principal.
Primeiro, clique em + para abrir uma nova sessão do Cloud Shell e não precisar encerrar o servidor:

Na nova sessão, alterne para o diretório grpc-hello-server:
$ cd grpc-hello-server
Em seguida, adicione a nova classe Client:
src/main/java/com/example/grpc/Client.java
package com.example.grpc;
import io.grpc.*;
public class Client
{
public static void main( String[] args ) throws Exception
{
// Channel is the abstraction to connect to a service endpoint
// Let's use plaintext communication because we don't have certs
final ManagedChannel channel = ManagedChannelBuilder.forTarget("localhost:8080")
.usePlaintext(true)
.build();
// It is up to the client to determine whether to block the call
// Here we create a blocking stub, but an async stub,
// or an async stub with Future are always possible.
GreetingServiceGrpc.GreetingServiceBlockingStub stub = GreetingServiceGrpc.newBlockingStub(channel);
GreetingServiceOuterClass.HelloRequest request =
GreetingServiceOuterClass.HelloRequest.newBuilder()
.setName("Ray")
.build();
// Finally, make the call using the stub
GreetingServiceOuterClass.HelloResponse response =
stub.greeting(request);
System.out.println(response);
// A Channel should be shutdown before stopping the process.
channel.shutdownNow();
}
}
Por fim, execute o cliente:
$ mvn -DskipTests package exec:java -Dexec.mainClass=com.example.grpc.Client ... greeting: "Hello there, Ray"
Pronto! Bem simples, não é?
5. Serviço de streaming
Há muito mais que você pode tentar. Por exemplo, é possível criar um serviço de streaming com facilidade adicionando a palavra-chave stream no arquivo proto ao parâmetro de solicitação ou de resposta. Por exemplo:
src/main/proto/GreetingService.proto
syntax = "proto3";
package com.example.grpc;
...
// Defining a Service, a Service can have multiple RPC operations
service GreetingService {
// MODIFY HERE: Update the return to streaming return.
rpc greeting(HelloRequest) returns (stream HelloResponse);
}
Atualize seu servidor para enviar várias respostas em vez de apenas uma. É possível fazer isso fazendo várias chamadas responseObserver.onNext(...):
src/main/java/com/example/grpc/GreetingServiceImpl.java
package com.example.grpc;
import io.grpc.stub.StreamObserver;
public class GreetingServiceImpl extends GreetingServiceGrpc.GreetingServiceImplBase {
@Override
public void greeting(GreetingServiceOuterClass.HelloRequest request,
StreamObserver<GreetingServiceOuterClass.HelloResponse> responseObserver) {
...
// Feel free to construct different responses if you'd like.
responseObserver.onNext(response);
responseObserver.onNext(response);
responseObserver.onNext(response);
// When you are done, you must call onCompleted.
responseObserver.onCompleted();
}
}
O cliente precisa usar um stub assíncrono em vez do stub de bloqueio. Atualize o código do cliente certificando-se de atualizar o tipo stub para GreetingServiceStub:
src/main/java/com/example/grpc/Client.java
package com.example.grpc;
import io.grpc.*;
// New import
import io.grpc.stub.*;
public class Client
{
public static void main( String[] args ) throws Exception
{
final ManagedChannel channel = ManagedChannelBuilder.forTarget("localhost:8080")
.usePlaintext(true)
.build();
// Replace the previous synchronous code with asynchronous code.
// This time use an async stub:
GreetingServiceGrpc.GreetingServiceStub stub = GreetingServiceGrpc.newStub(channel);
// Construct a request
GreetingServiceOuterClass.HelloRequest request =
GreetingServiceOuterClass.HelloRequest.newBuilder()
.setName("Ray")
.build();
// Make an Asynchronous call. Listen to responses w/ StreamObserver
stub.greeting(request, new StreamObserver<GreetingServiceOuterClass.HelloResponse>() {
public void onNext(GreetingServiceOuterClass.HelloResponse response) {
System.out.println(response);
}
public void onError(Throwable t) {
}
public void onCompleted() {
// Typically you'll shutdown the channel somewhere else.
// But for the purpose of the lab, we are only making a single
// request. We'll shutdown as soon as this request is done.
channel.shutdownNow();
}
});
}
}
Recrie o aplicativo:
$ mvn -DskipTests package
Reinicie o servidor e o cliente na própria sessão do Cloud Shell.
Para iniciar o servidor:
$ mvn exec:java -Dexec.mainClass=com.example.grpc.App ... Server Started
Para iniciar o cliente:
$ mvn exec:java -Dexec.mainClass=com.example.grpc.Client ... greeting: "Hello there, Ray" greeting: "Hello there, Ray" greeting: "Hello there, Ray"
6. Parabéns!
O que vimos:
- A linguagem do buffer de protocolo
- Como implementar um servidor gRPC usando Java
- Como implementar um cliente gRPC usando Java.
Próximas etapas:
- Saiba mais sobre o gRPC Java
- Confira mais exemplos de gRPC em Java no GitHub (em inglês)
- Saiba mais sobre Streaming no gRPC.
- Saiba mais sobre transcodificação gRPC para REST.
Envie um feedback
- Reserve um momento para completar nossa pesquisa curta