spiral/grpc-client
Powerful, extensible gRPC client for PHP with a simple Guzzle-like API. Make unary and streaming calls, add interceptors like timeouts and retries, and integrate easily with Spiral or use standalone. Requires the gRPC extension.
Architecture fit
spiral/roadrunner-bridge >= 4.0.0 bundles it and supplies the bootloader and config flow. For a Spiral service that already exposes gRPC servers via protoc-gen-php-grpc, adopting the client adds no new conceptual model — same DI container, same interceptor idiom, same generated interface types.grpc extension, and (2) it only accepts service interfaces generated by Spiral's protoc-gen-php-grpc plugin — not the stubs produced by the standard grpc/grpc + google/protobuf toolchain. This is not a drop-in replacement for an existing grpc/grpc PHP client; the generated contracts are different types. Any TPM assumption that "it's just a PHP gRPC client, we can point it at our existing protos" should be killed early.GrpcClient (added in 1.0.0-rc2) materially improves fit outside Spiral. A Guzzle-like GrpcClient::create('host:port') with immutable with* derivation, withFactory() for container-based interceptor resolution, and a ServiceClientProvider path for other frameworks means Laravel adoption is feasible without pulling in Spiral's kernel. But the standalone path deliberately drops per-service interceptors — teams needing those must adopt the full GrpcClientConfig + ExecuteServiceInterceptors machinery, which is a meaningful complexity step up.Integration feasibility
composer require spiral/grpc-client -W, install the PECL extension, generate interfaces, register the bootloader or instantiate the standalone client. Documentation is above average for a 40-star package — DTO config examples, interceptor ordering semantics, and a TLS example are all present.grpc extension at a version compatible with our PHP line. That is a one-time but non-trivial infrastructure task, and it is the single most likely source of schedule slip..proto files need generation through protoc-gen-php-grpc and the resulting interfaces wired into config. Budget this as a per-service cost, not a one-off.Technical risk
roadrunner-bridge bundles the package rather than requiring it directly. Treat this as "unproven outside the vendor's own ecosystem" rather than "unused."protoc plugin, and the RoadRunner integration. That's coherent, but it means schema tooling and transport client move together — a lock-in vector worth naming explicitly to stakeholders.RetryInterceptor exposes attempts, initial interval, and backoff coefficient; jitter and idempotency awareness are not documented. Retrying non-idempotent writes is a correctness hazard, not just a performance knob — this needs an explicit policy per RPC, owned by the service team, not left to defaults.Key questions
protoc-gen-php-grpc, or do we have existing grpc/grpc stubs we cannot move? A "no" here ends the evaluation.Stack fit
.proto files, and calls one or two upstream gRPC services. Here the standalone GrpcClient is genuinely pleasant — one create() call, interceptors via createConfig() factories, and a thin service-locator binding for framework injection.grpc/grpc-generated clients and no appetite for RoadRunner. Do not proceed; the contract-generation mismatch alone makes this a rewrite of every client call site.MailSenderClient) regardless of path. The package's own API is pre-1.0; our ports must not be.Migration path
GrpcClient, and centralize client construction in one factory so configuration and interceptors are not scattered across call sites.Compatibility
grpc build; verify the extension ships for our target PHP minor before the spike, since this is the classic late-breaking blocker.ExecuteServiceInterceptors must be positioned deliberately in the chain, and interceptor order determines whether timeouts apply per-attempt or in aggregate. Encode the chosen policy in the adapter, not in per-service config files.roadrunner-bridge; treat the bridge as the versioning boundary and upgrade them together.Sequencing
Extension availability and proto generation come first because they are binary gates. Adapter abstraction comes second because it is the exit option. Pilot comes third because it is where retry, TLS, and observability assumptions get falsified. Nothing touches a write path until the retry policy has an owner and a documented idempotency stance.
Maintenance
Support
Scaling
ConnectionsRotationInterceptor to distribute load or fail over. Adequate for typical internal service meshes; not a substitute for proper service-side load balancing or a sidecar.Failure modes
Ramp-up
roadrunner-bridge handles wiring.protoc-gen-php-grpc toolchain and the DTO config model if per-service interceptors are needed.Recommendation: position as Evaluate, not Adopt — conditional go if we are on Spiral/RoadRunner with gRPC already in play, defer if we are a PHP-FPM shop with no current gRPC traffic. Gate production on four artifacts: working extension in CI, CA trust-root confirmation from security, a written timeout/retry policy per RPC, and a merged adapter layer that makes swapping the transport a one-file change.
How can I help you explore Laravel packages today?