PHP Academy · Aula

Comunicação entre serviços: REST e gRPC

Conecte serviços de forma síncrona e eficiente.

Aula 2 de 413 etapas

Comunicação entre serviços: REST e gRPC é uma aula grátis de PHP Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de PHP Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de PHP Academy inclui 4 aulas no total.

REST e gRPC

Os serviços precisam se comunicar de forma síncrona: uma requisição é enviada e uma resposta retorna. As duas opções predominantes são REST sobre HTTP/JSON e gRPC sobre HTTP/2 + Protobuf. Elas são otimizadas para objetivos diferentes — REST para alcance e facilidade de uso por pessoas, gRPC para velocidade e contratos rigorosos.

Esta lição apresenta as duas opções sob a perspectiva do PHP e explica quando escolher cada uma.

REST: a língua franca

REST modela recursos por trás de URLs e usa verbos HTTP e códigos de status para expressar semântica. Seus pontos fortes são as ferramentas universais, a possibilidade de armazenamento em cache, a facilidade de depuração com curl e a ausência de necessidade de um cliente especial. Seus pontos fracos são o JSON verboso, a falta de um esquema obrigatório e o suporte apenas a requisições e respostas.

Para APIs públicas e pontos de acesso voltados ao navegador, REST quase sempre é a escolha certa.

Chamando um serviço REST

Use um cliente HTTP PSR-18 (Guzzle neste caso). Sempre defina um tempo limite de conexão e de requisição — uma chamada sem limite para um serviço lento pode esgotar os processos do PHP-FPM e causar uma indisponibilidade em cascata.

<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;

$http = new Client([
    'base_uri'        => 'http://customers-svc/',
    'connect_timeout' => 1.0,  // never block forever on connect
    'timeout'         => 3.0,  // total request budget
    'http_errors'     => false,
]);

$res = $http->get('customers/42', ['headers' => ['Accept' => 'application/json']]);
if ($res->getStatusCode() === 200) {
    $customer = json_decode((string) $res->getBody(), true);
    echo $customer['email'] . "\n";
}

Os códigos de status são o contrato

Na comunicação REST entre serviços, os códigos de status HTTP são o seu protocolo de erros. Trate-os deliberadamente:

  • 2xx indica sucesso; 4xx indica falha do chamador (não faça novas tentativas sem critério); 5xx/tempos limite permitem novas tentativas.
  • Use 409 para conflitos, 422 para validação e 429 para limites de taxa (respeite Retry-After).

Fazer uma nova tentativa para um 400 apenas desperdiça chamadas; repetir um 503 com espera progressiva é correto.

<?php
function isRetryable(int $status): bool {
    return $status === 0          // timeout/connection error
        || $status === 429
        || ($status >= 500 && $status !== 501);
}
var_dump(isRetryable(503)); // true
var_dump(isRetryable(400)); // false

gRPC: contrato em primeiro lugar e alta velocidade

gRPC usa Protocol Buffers: você define serviços e mensagens em um arquivo .proto e depois gera esqueletos de cliente/servidor fortemente tipados. Sobre HTTP/2, com Protobuf binário, ele é muito mais compacto e tem menor latência que JSON, além de oferecer transmissão contínua.

syntax = "proto3";
package customers;

service Customers {
  rpc GetCustomer (GetCustomerRequest) returns (Customer);
}

message GetCustomerRequest { string id = 1; }
message Customer {
  string id = 1;
  string email = 2;
  int32  loyalty_points = 3;
}

Gerando esqueletos PHP

Instale a extensão gRPC do PHP e o plugin protoc; depois, gere classes de cliente a partir do arquivo .proto. O PHP pode atuar como um cliente gRPC completo por meio de ext-grpc; executar um servidor gRPC nativo em PHP normalmente exige Roadrunner ou Swoole.

pecl install grpc
composer require grpc/grpc google/protobuf

protoc --proto_path=. \
  --php_out=./generated \
  --grpc_out=./generated \
  --plugin=protoc-gen-grpc=$(which grpc_php_plugin) \
  customers.proto

Uma chamada de cliente gRPC

Os esqueletos gerados fornecem requisições e respostas tipadas. Uma chamada gRPC retorna a mensagem e um objeto status — sempre verifique o código de status antes de confiar na resposta.

<?php
require 'vendor/autoload.php';
use Customers\CustomersClient;
use Customers\GetCustomerRequest;
use Grpc\ChannelCredentials;

$client = new CustomersClient('customers-svc:50051', [
    'credentials' => ChannelCredentials::createInsecure(),
]);

$req = (new GetCustomerRequest())->setId('42');
[$reply, $status] = $client->GetCustomer($req)->wait();

if ($status->code === \Grpc\STATUS_OK) {
    echo $reply->getEmail(), "\n";
} else {
    fwrite(STDERR, "gRPC error: {$status->details}\n");
}

Evolução do esquema

O Protobuf foi projetado para oferecer compatibilidade com versões futuras e anteriores — desde que você respeite suas regras:

  • Nunca reutilize nem altere o número de um campo. Adicione novos campos usando novos números.
  • Marque os campos removidos como reserved para impedir que o número seja reutilizado.
  • Os clientes antigos ignoram campos desconhecidos; os campos ausentes recebem os valores padrão do tipo.

JSON/REST não oferece nada disso gratuitamente — você impõe a compatibilidade por convenção (e, idealmente, usando um esquema OpenAPI compartilhado com testes de contrato).

message Customer {
  string id = 1;
  string email = 2;
  reserved 3;            // old 'loyalty_points', never reuse 3
  reserved "loyalty_points";
  string display_name = 4; // new field, safe additive change
}

Transmissão contínua

gRPC oferece quatro tipos de chamada; REST oferece nativamente apenas o primeiro:

  • Unária — uma requisição, uma resposta.
  • Transmissão pelo servidor — uma requisição, um fluxo de respostas (por exemplo, atualizações ao vivo).
  • Transmissão pelo cliente — um fluxo de requisições, uma resposta (por exemplo, envio em massa).
  • Bidirecional — ambos transmitem simultaneamente.

Se o seu caso de uso envolve envio direto ou um fluxo de dados duradouro, a transmissão contínua do gRPC é melhor que consultas periódicas a um ponto de acesso REST.

Propagação do contexto e dos prazos

As chamadas síncronas formam cadeias, portanto dois elementos devem acompanhar cada requisição: um identificador de correlação/rastreamento para o rastreamento de ponta a ponta e um prazo para impedir que um serviço final lento faça toda a cadeia travar. O gRPC oferece prazos nativos; no REST, você os simula com um orçamento decrescente de tempo limite transmitido aos serviços seguintes.

<?php
// REST: shrink the remaining budget as the call chain deepens
function forwardHeaders(array $incoming, float $remainingMs): array {
    return [
        'X-Correlation-Id' => $incoming['X-Correlation-Id'] ?? bin2hex(random_bytes(8)),
        // downstream must finish within what's left of our budget
        'X-Timeout-Ms'     => (string) max(0, (int) $remainingMs),
    ];
}
print_r(forwardHeaders(['X-Correlation-Id' => 'trace-9'], 1500));

Escolhendo entre eles

Um guia prático para a decisão:

  • REST para APIs públicas/de parceiros, clientes de navegador, CRUD simples, depuração fácil e amplo suporte a cache.
  • gRPC para chamadas internas entre serviços de alto volume e baixa latência, contratos tipados rigorosos e transmissão contínua.

Muitos sistemas usam ambos: gRPC entre serviços, atrás da porta de entrada, e REST na borda para o mundo externo. Não force uma ferramenta a fazer o trabalho da outra.

Verificação rápida

Associando o protocolo ao caso de uso.

Recapitulação

Comunicação síncrona entre serviços:

  • REST/JSON — universal, fácil de depurar e compatível com cache; os códigos de status são o contrato; sempre defina tempos limite.
  • gRPC/Protobuf — contrato em primeiro lugar, compacto, rápido e com transmissão contínua; gere esqueletos PHP tipados.
  • Decida se é possível fazer uma nova tentativa com base nos códigos de status/gRPC; nunca repita erros do cliente.
  • Evolua os esquemas de forma aditiva — nunca reutilize números de campos do Protobuf.
  • REST na borda e gRPC entre serviços internos é uma divisão comum e sólida.

A seguir: roteamento e localização de todos esses serviços com portas de entrada e descoberta.

Grátis para começar

Aprenda PHP com um tutor de IA — grátis

Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.

Cursos
49
Aulas
195

Perguntas Frequentes

A aula “Comunicação entre serviços: REST e gRPC” é grátis?

Sim — o texto completo de “Comunicação entre serviços: REST e gRPC” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de PHP Academy, atualize para CoddyKit PRO. O curso de PHP Academy inclui 4 aulas no total.

O que vou aprender em “Comunicação entre serviços: REST e gRPC”?

Conecte serviços de forma síncrona e eficiente. Você pratica PHP Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar PHP Academy?

Nenhuma experiência prévia é necessária. PHP Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.

Quanto tempo leva a aula “Comunicação entre serviços: REST e gRPC”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de PHP Academy?

Sim. Cada aula de PHP Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Do monólito aos microsserviços
  2. Comunicação entre serviços: REST e gRPC
  3. Gateways de API e descoberta de serviços
  4. Resiliência: disjuntores e novas tentativas
← Voltar para PHP Academy