gRPC
debt(d7/e7/b7/t5)
Closest to 'only careful code review or runtime testing' (d7). The detection_hints note automated=no, and while tools like grpc, protoc, and buf help validate schemas, misuse patterns — such as using gRPC for public-facing APIs, missing status code handling, or wrong streaming strategy — are not caught by these tools automatically. They surface only in code review or when integration issues appear in testing/staging.
Closest to 'cross-cutting refactor across the codebase' (e7). The quick_fix describes generating PHP client stubs and defining .proto schemas across services. Common mistakes like not versioning proto files or using gRPC for public APIs require touching multiple services, regenerating stubs, updating consumers, and potentially adding proxy layers — a cross-cutting remediation effort affecting all service boundaries.
Closest to 'strong gravitational pull' (e7 → b7). gRPC shapes every inter-service communication contract: proto files must be maintained and versioned, all consumers must regenerate stubs on schema changes, TLS configuration spans services, and the applies_to scope covers cli and queue-worker contexts. Every future API change is filtered through the proto schema contract, creating strong gravitational pull on the entire system's service boundaries.
Closest to 'notable trap' (t5). The misconception field explicitly states the canonical wrong belief: 'gRPC is always faster than REST.' This is a documented gotcha — developers choose gRPC expecting universal performance gains but encounter browser incompatibility requiring a proxy, harder debugging, and schema overhead that makes it impractical for simple CRUD or public APIs. This is a well-known but non-obvious trap.
Also Known As
TL;DR
Explanation
gRPC (Google Remote Procedure Call) uses Protocol Buffers (.proto files) to define strongly-typed service contracts that generate client and server stubs in multiple languages. Over HTTP/2 it provides: unary calls (request/response), server streaming, client streaming, and bidirectional streaming. Compared to REST+JSON: gRPC is ~5–10x faster in serialisation, enforces schema contracts at compile time, supports streaming natively, but is harder to debug (binary protocol), requires HTTP/2, and has less ecosystem support. In PHP: grpc/grpc PECL extension + google/protobuf Composer package. Used for internal microservice communication where performance and schema enforcement matter more than browser accessibility.
Diagram
flowchart LR
subgraph Proto_Definition
PROTO[payment.proto<br/>rpc Charge returns Receipt]
end
PROTO -->|protoc generate| PHP_CLIENT[PHP Client stub]
PROTO -->|protoc generate| SERVER[Server skeleton<br/>any language]
PHP_CLIENT -->|HTTP/2 + binary protobuf| SERVER
subgraph vs_REST
REST2[REST JSON<br/>text slower flexible]
GRPC2[gRPC binary<br/>fast typed streaming]
end
style PROTO fill:#6e40c9,color:#fff
style PHP_CLIENT fill:#1f6feb,color:#fff
style SERVER fill:#238636,color:#fff
style GRPC2 fill:#238636,color:#fff
style REST2 fill:#d29922,color:#fff
Common Misconception
Why It Matters
Common Mistakes
- Using gRPC for public-facing APIs — browsers cannot make native gRPC calls without a proxy layer.
- Not versioning proto files — changes to a proto schema without backward compatibility breaks all consumers.
- Not handling gRPC status codes correctly — treating every non-OK as a generic error loses retry and fallback logic.
- Ignoring streaming capabilities — unary RPC where server-streaming would reduce latency misses the protocol's strength.
Code Examples
// Unversioned proto — breaking change with no migration path:
syntax = "proto3";
message User {
int32 id = 1;
string email = 2;
// Field 3 removed — existing clients that expected it will fail silently
// Never remove fields; mark deprecated and add new fields with new numbers
}
// gRPC in PHP — high-performance RPC using Protocol Buffers
// 1. Define service in .proto:
// service OrderService {
// rpc PlaceOrder (PlaceOrderRequest) returns (PlaceOrderResponse);
// }
// 2. Generate PHP stubs:
$ protoc --php_out=. --grpc_out=. orders.proto
// 3. Client usage:
\$channel = new Grpc\Channel('orders-service:50051', ['credentials' => Grpc\ChannelCredentials::createInsecure()]);
\$client = new OrderServiceClient('orders-service:50051', [], \$channel);
\$request = new PlaceOrderRequest();
\$request->setUserId(42);
\$request->setTotal(1999);
[\$response, \$status] = \$client->PlaceOrder(\$request)->wait();
if (\$status->code !== Grpc\STATUS_OK) throw new \RuntimeException(\$status->details);
echo \$response->getOrderId();