0Pricing
PHP Academy · Lekcja

Komunikacja usług: REST i gRPC

Łącz usługi synchronicznie i wydajnie

Komunikacja usług: REST i gRPC to bezpłatna lekcja PHP Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej PHP Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs PHP Academy zawiera 4 lekcji w sumie.

REST i gRPC

Usługi muszą komunikować się synchronicznie: wysyłane jest żądanie, a następnie wraca odpowiedź. Dwie dominujące możliwości to REST przez HTTP/JSON oraz gRPC przez HTTP/2 + Protobuf. Optymalizują one różne aspekty — REST zapewnia szeroki zasięg i przyjazność dla człowieka, a gRPC szybkość i ścisłe kontrakty.

W tej lekcji pokazano oba rozwiązania z perspektywy PHP oraz wyjaśniono, kiedy wybrać każde z nich.

REST: wspólny język

REST odwzorowuje zasoby za pomocą adresów URL i wykorzystuje metody HTTP oraz kody stanu do określania semantyki. Jego zalety to uniwersalne narzędzia, możliwość cachowania, łatwe debugowanie za pomocą curl oraz brak wymogu używania specjalnego klienta. Wady to rozwlekły JSON, brak narzuconego schematu i obsługa wyłącznie modelu żądanie/odpowiedź.

W przypadku publicznych interfejsów API i punktów końcowych używanych przez przeglądarki REST jest niemal zawsze właściwym wyborem.

Wywoływanie usługi REST

Należy używać klienta HTTP zgodnego z PSR-18 (tutaj Guzzle). Zawsze ustawiać limit czasu połączenia i żądania — wywołanie bez limitu czasu do powolnej usługi równorzędnej może wyczerpać procesy PHP-FPM i doprowadzić do kaskadowej awarii.

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

Kody stanu są kontraktem

W komunikacji REST między usługami kody stanu HTTP stanowią protokół obsługi błędów. Należy używać ich świadomie:

  • 2xx oznacza powodzenie; 4xx oznacza błąd po stronie wywołującego (nie należy bezmyślnie ponawiać żądania); 5xx i przekroczenia limitu czasu można ponawiać.
  • Używać 409 w przypadku konfliktów, 422 w przypadku błędów walidacji oraz 429 po przekroczeniu limitu żądań (przestrzegać Retry-After).

Ponawianie żądania 400 tylko marnuje wywołania; ponowienie żądania 503 z wykorzystaniem narastających opóźnień jest właściwe.

<?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: kontrakt przede wszystkim i szybkość

gRPC wykorzystuje Protocol Buffers: w pliku .proto definiuje się usługi i komunikaty, a następnie generuje silnie typowane klasy pośredniczące klienta i serwera. Dzięki użyciu binarnego Protobuf przez HTTP/2 rozwiązanie to jest znacznie bardziej zwarte i zapewnia mniejsze opóźnienia niż JSON, a także obsługuje strumieniowanie.

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

Generowanie stubów PHP

Należy zainstalować rozszerzenie gRPC dla PHP oraz wtyczkę protoc, a następnie wygenerować klasy klienta na podstawie pliku .proto. PHP może działać jako w pełni funkcjonalny klient gRPC za pośrednictwem ext-grpc; uruchomienie natywnego serwera gRPC w PHP zazwyczaj wymaga użycia Roadrunner lub 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

Wywołanie klienta gRPC

Wygenerowane stuby udostępniają typowane żądania i odpowiedzi. Wywołanie gRPC zwraca komunikat oraz obiekt status — przed zaufaniem odpowiedzi zawsze należy sprawdzić kod stanu.

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

Ewolucja schematu

Protobuf został zaprojektowany z myślą o kompatybilności w przód i wstecz — pod warunkiem przestrzegania jego zasad:

  • Nigdy nie używać ponownie ani nie zmieniać numeru pola. Nowe pola dodawać z nowymi numerami.
  • Usunięte pola oznaczać jako reserved, aby nie można było ponownie wykorzystać ich numeru.
  • Starsze klienty ignorują nieznane pola, a brakujące pola otrzymują wartości domyślne swoich typów.

JSON/REST nie zapewnia tego automatycznie — zgodność należy wymuszać konwencją (a najlepiej także współdzielonym schematem OpenAPI i testami kontraktowymi).

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
}

Strumieniowanie

gRPC obsługuje cztery typy wywołań; REST natywnie obsługuje tylko pierwszy z nich:

  • Unary — jedno żądanie, jedna odpowiedź.
  • Strumieniowanie po stronie serwera — jedno żądanie i strumień odpowiedzi (np. aktualizacje na żywo).
  • Strumieniowanie po stronie klienta — strumień żądań i jedna odpowiedź (np. przesyłanie zbiorcze).
  • Dwukierunkowe — oba strumienie działają jednocześnie.

Jeśli przypadek użycia obejmuje wypychanie danych lub długotrwały przepływ danych, strumieniowanie gRPC sprawdza się lepiej niż odpytywanie punktu końcowego REST.

Przekazywanie kontekstu i terminów wykonania

Wywołania synchroniczne tworzą łańcuchy, dlatego z każdym żądaniem muszą być przekazywane dwie informacje: identyfikator korelacji lub śledzenia do śledzenia całego przebiegu oraz termin wykonania, aby wolny element końcowy nie zawiesił całego łańcucha. gRPC zapewnia natywną obsługę terminów wykonania; w REST można je zasymulować za pomocą malejącego budżetu czasu przekazywanego dalej.

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

Wybór między nimi

Praktyczny przewodnik po wyborze:

  • REST do publicznych interfejsów API i interfejsów partnerskich, klientów przeglądarkowych, prostych operacji CRUD, łatwego debugowania oraz szerokiej obsługi cachowania.
  • gRPC do wewnętrznych wywołań między usługami o dużym natężeniu ruchu i małych opóźnieniach, ścisłych kontraktów z typowaniem oraz strumieniowania.

Wiele systemów korzysta z obu rozwiązań: gRPC działa za bramą między usługami, a REST na brzegu systemu, dla świata zewnętrznego. Nie należy zmuszać jednego narzędzia do wykonywania pracy właściwej dla drugiego.

Szybki test

Dopasowywanie protokołu do przypadku użycia.

Podsumowanie

Synchroniczna komunikacja między usługami:

  • REST/JSON — uniwersalny, łatwy do debugowania i cachowania; kody stanu są kontraktem; zawsze należy ustawiać limity czasu.
  • gRPC/Protobuf — kontrakt przede wszystkim, zwarta forma, szybkość i strumieniowanie; należy generować typowane stuby PHP.
  • O możliwości ponawiania decydować na podstawie kodów statusu lub gRPC; nigdy nie ponawiać błędów klienta.
  • Ewoluować schematy przez dodawanie elementów — nigdy nie używać ponownie numerów pól Protobuf.
  • REST na brzegu systemu i gRPC między usługami wewnętrznymi to popularny i rozsądny podział.

Następnie: routowanie i lokalizowanie wszystkich tych usług za pomocą bram i mechanizmów wykrywania usług.

Często zadawane pytania

Czy lekcja „Komunikacja usług: REST i gRPC” jest bezpłatna?

Tak — pełny tekst „Komunikacja usług: REST i gRPC” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu PHP Academy, przejdź na CoddyKit PRO. Kurs PHP Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Komunikacja usług: REST i gRPC”?

Łącz usługi synchronicznie i wydajnie Ćwiczysz PHP Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć PHP Academy?

Nie wymagamy żadnego doświadczenia. PHP Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Komunikacja usług: REST i gRPC”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji PHP Academy?

Tak. Każda lekcja PHP Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Od monolitu do mikroserwisów
  2. Komunikacja usług: REST i gRPC
  3. Bramy API i wykrywanie usług
  4. Odporność: circuit breakery i ponowienia
← Powrót do PHP Academy