0Pricing
PHP Academy · Lezione

Comunicazione tra servizi: REST e gRPC

Colleghi i servizi in modo sincrono ed efficiente

Comunicazione tra servizi: REST e gRPC è una lezione PHP Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento PHP Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso PHP Academy include 4 lezioni in totale.

REST e gRPC

I servizi devono comunicare in modo sincrono: una richiesta parte e una risposta torna indietro. Le due scelte predominanti sono REST su HTTP/JSON e gRPC su HTTP/2 + Protobuf. Sono ottimizzate per esigenze diverse: REST per ampia accessibilità e facilità d'uso, gRPC per velocità e contratti rigorosi.

Questa lezione mostra entrambi gli approcci dal punto di vista di PHP e spiega quando scegliere l'uno o l'altro.

REST: la lingua franca

REST modella le risorse tramite URL e utilizza i verbi HTTP e i codici di stato per definirne la semantica. I suoi punti di forza sono gli strumenti universali, la possibilità di caching, la facilità di debug con curl e l'assenza di requisiti speciali per il client. I suoi punti deboli sono il JSON verboso, l'assenza di uno schema obbligatorio e il modello limitato a richiesta e risposta.

Per le API pubbliche e gli endpoint rivolti al browser, REST è quasi sempre la scelta giusta.

Chiamare un servizio REST

Utilizzi un client HTTP PSR-18 (qui Guzzle). Imposti sempre un timeout di connessione e di richiesta: una chiamata senza limiti a un servizio lento può esaurire i worker PHP-FPM e propagare l'interruzione del servizio.

<?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";
}

I codici di stato sono il contratto

Nelle comunicazioni REST tra servizi, i codici di stato HTTP sono il protocollo degli errori. Li gestisca in modo esplicito:

  • 2xx indica un successo; 4xx un errore del chiamante (non riprovi alla cieca); 5xx e i timeout consentono un nuovo tentativo.
  • Utilizzi 409 per i conflitti, 422 per la validazione e 429 per i limiti di frequenza (rispetti Retry-After).

Riprovare un 400 spreca soltanto chiamate; riprovare un 503 con backoff è corretto.

<?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: prima il contratto e veloce

gRPC utilizza Protocol Buffers: si definiscono servizi e messaggi in un file .proto, quindi si generano stub client/server fortemente tipizzati. Grazie a HTTP/2 e a Protobuf binario, è molto più compatto e offre una latenza inferiore rispetto a JSON; inoltre supporta lo streaming.

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;
}

Generazione degli stub PHP

Installi l'estensione gRPC per PHP e il plugin protoc, quindi generi le classi client dal file .proto. PHP può agire come client gRPC completo tramite ext-grpc; per eseguire un server gRPC nativo in PHP sono in genere necessari Roadrunner o 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

Una chiamata client gRPC

Gli stub generati forniscono richieste e risposte tipizzate. Una chiamata gRPC restituisce il messaggio e un oggetto status: controlli sempre il codice di stato prima di considerare attendibile la risposta.

<?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");
}

Evoluzione dello schema

Protobuf è progettato per la compatibilità in avanti e all'indietro, se se ne rispettano le regole:

  • Non riutilizzi né modifichi mai il numero di un campo. Aggiunga i nuovi campi con numeri nuovi.
  • Contrassegni i campi rimossi come reserved, in modo che il numero non possa essere riutilizzato.
  • I client meno recenti ignorano i campi sconosciuti; i campi mancanti assumono i valori predefiniti del tipo.

JSON/REST non offre nulla di tutto questo automaticamente: la compatibilità viene garantita per convenzione, idealmente con uno schema OpenAPI condiviso e contract test.

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
}

Streaming

gRPC supporta quattro tipi di chiamata; REST supporta nativamente solo il primo:

  • Unaria: una richiesta e una risposta.
  • Streaming dal server: una richiesta e un flusso di risposte (ad esempio aggiornamenti in tempo reale).
  • Streaming dal client: un flusso di richieste e una risposta (ad esempio un caricamento in blocco).
  • Bidirezionale: entrambi i flussi procedono contemporaneamente.

Se il caso d'uso prevede dati inviati dal server o un flusso di dati di lunga durata, lo streaming gRPC è migliore del polling di un endpoint REST.

Propagazione del contesto e delle scadenze

Le chiamate sincrone formano catene, quindi due elementi devono accompagnare ogni richiesta: un ID di correlazione/tracciamento per il tracing end-to-end e una scadenza, affinché un servizio lento in fondo alla catena non la blocchi interamente. gRPC supporta le scadenze nativamente; in REST le si emula passando a valle un budget di timeout residuo.

<?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));

Scegliere tra i due

Una guida pratica alla scelta:

  • REST per API pubbliche o per partner, client browser, semplici operazioni CRUD, facilità di debug e ampio supporto per la cache.
  • gRPC per chiamate interne tra servizi ad alto volume e bassa latenza, contratti tipizzati rigorosi e streaming.

Molti sistemi utilizzano entrambi: gRPC dietro il gateway, tra i servizi, e REST al confine verso il mondo esterno. Non costringa uno strumento a svolgere il compito dell'altro.

Verifica rapida

Associare il protocollo al caso d'uso.

Riepilogo

Comunicazione sincrona tra servizi:

  • REST/JSON: universale, facile da sottoporre a debug e memorizzabile nella cache; i codici di stato sono il contratto; imposti sempre i timeout.
  • gRPC/Protobuf: contratto prima di tutto, compatto, veloce e con supporto allo streaming; generi stub PHP tipizzati.
  • Decida se ritentare in base ai codici di stato o gRPC; non ritenti mai gli errori del client.
  • Faccia evolvere gli schemi in modo additivo: non riutilizzi mai i numeri dei campi Protobuf.
  • REST al confine e gRPC tra i servizi interni rappresentano una suddivisione comune e corretta.

Prossimo argomento: instradare e individuare tutti questi servizi tramite gateway e service discovery.

Domande Frequenti

La lezione «Comunicazione tra servizi: REST e gRPC» è gratuita?

Sì — il testo completo di «Comunicazione tra servizi: REST e gRPC» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso PHP Academy, passa a CoddyKit PRO. Il corso PHP Academy include 4 lezioni in totale.

Cosa imparerò in «Comunicazione tra servizi: REST e gRPC»?

Colleghi i servizi in modo sincrono ed efficiente Eserciti PHP Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare PHP Academy?

Non è richiesta alcuna esperienza precedente. PHP Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «Comunicazione tra servizi: REST e gRPC»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione PHP Academy?

Sì. Ogni lezione PHP Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Dal monolite ai microservizi
  2. Comunicazione tra servizi: REST e gRPC
  3. API Gateway e individuazione dei servizi
  4. Resilienza: circuit breaker e retry
← Torna a PHP Academy