For the complete documentation index, see llms.txt. This page is also available as Markdown.

Intro into gRPC

RoadRunner gRPC plugin enables PHP applications to communicate with gRPC clients.

It consists of two main parts:

  1. protoc-plugin protoc-gen-php-grpc: This is a plugin for the protoc compiler that generates PHP code from a gRPC service definition file (.proto). It generates PHP classes that correspond to the service definition and message types. These classes provide an interface for handling incoming gRPC requests and sending responses back to the client.

  2. gRPC server: This is a server that starts PHP workers and listens for incoming gRPC requests. It receives requests from gRPC clients, proxies them to the PHP workers, and sends the responses back to the client. The server is responsible for managing the lifecycle of the PHP workers and ensuring that they are available to handle requests.

For custom gRPC interceptor plugins, see Interceptors.

Protoc-plugin

The first step is to define a .proto file that describes the gRPC service and messages that your PHP application will handle.

In our documentation, we will use the following example of a .proto file that is stored in the <app>/proto directory:

proto/helloworld.proto
syntax = "proto3";

option go_package = "proto/greeter";
option php_namespace = "GRPC\\Greeter";
option php_metadata_namespace = "GRPC\\GPBMetadata";

package helloworld;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

It defines a simple gRPC service called Greeter that takes a name as input and returns a greeting.

The php_namespace and php_metadata_namespace options allow you to specify the namespaces to use in the generated DTO and Service interface.

Generating PHP code

Use protoc 36.1 and Go 1.27.1. Install the RoadRunner generator from its pinned source revision:

Add the Go binary installation directory to PATH. Create the generated directory before running protoc.

The PHP generator uses the separate protoc_plugins/v5 module. Its module version is independent of the gRPC plugin v6.

Here's an example command:

Make sure that the generated directory exists and is writable.

After running the command, you can find the generated DTO and GreeterInterface files in the <app>/generated/GRPC/Greeter directory.

We recommend also registering the GRPC namespace in the composer.json file:

By doing this, you can easily use the generated PHP classes in your application.

Using BUF plugin

You can also use the BUF RoadRunner gRPC plugin to generate PHP code from the .proto file instead of using the protoc compiler.

To use BUF to generate PHP gRPC services, you'll need to create two files: buf.yaml and buf.gen.yaml.

Here's an example of a buf.yaml file:

The module contains the .proto files in proto/. If your files import external schemas, add their Buf modules under deps, run buf dep update, and keep the resulting buf.lock with your source files.

Here's an example of a buf.gen.yaml file:

Run buf generate from the directory that contains buf.yaml and buf.gen.yaml. The configuration pins each generator version and uses the RoadRunner plugin to generate PHP gRPC services.

For Buf output, set the GRPC\\ Composer autoload path to generated/php/GRPC. The example also generates Go and Python code.

PHP Client

The RoadRunner gRPC plugin comes with a convenient PHP package that simplifies the process of integrating the plugin with your PHP application.

Installation

You can install the package via Composer using the following command:

Implement Service

Next, you will need to create a PHP class that implements the Greeter service defined in the .proto file. This class should implement the GRPC/Greeter/GreeterInterface.

Here's an example:

Usage

To use the Greeter service, you can create a PHP worker that registers the service with the gRPC server.

Here's an example of how to do this:

After creating the worker, you need to configure RoadRunner to register the proto/helloworld.proto service.

Here's an example configuration:

You can define command to start server in the server.command section. It will be used to start PHP workers for all registered plugins, such as grpc, http, jobs, etc.

You can also define command to start server in the grpc.pool.command section to separate server and grpc workers.

You can list multiple proto files or glob patterns in the proto section. Glob patterns have been supported since RoadRunner v2025.1.9.

After configuring the server, you can start it using the following command:

This will start the gRPC server and make the Greeter service available for remote clients to call. You can use any gRPC client library in any language that supports gRPC to call the SayHello method.

To quickly verify your code's correctness, you can install grpc-client-cli which provides an interactive CLI tool for talking to gRPC services.

To access the Greeter service with grpc-client-cli run the following in a terminal:

grpc-client-cli --proto proto/helloworld.proto 127.0.0.1:9001

It will provide some interactive prompts asking you what service and method you want to call

You will then be prompted to manually form the JSON payload it expects and upon pressing enter, your Greeter service should respond in an amicable manner:

With debug logging enabled, RoadRunner writes records such as:

Congratulations on being able to communicate over gRPC to PHP using Roadrunner!

Metrics

RoadRunner has a metrics plugin that provides metrics for the gRPC server, which can be used with Prometheus and a preconfigured Grafana dashboard

grpc-metrics

mTLS

To enable mTLS use the following configuration:

require_and_verify_client_cert requires a client certificate signed by a trusted CA. request_client_cert only requests a certificate; it does not require or verify one.

Options for the client_auth_type are:

  • request_client_cert

  • require_any_client_cert

  • verify_client_cert_if_given

  • require_and_verify_client_cert

  • no_client_certs

Server reflection

The gRPC plugin enables server reflection on the gRPC listen port. Both the v1 and v1alpha reflection APIs are available without an enable flag.

Without a descriptor registry, reflection lists registered services but cannot return the file and message descriptors for PHP services. Configure the bundled Protoreg plugin with the same service definitions used by grpc.proto to provide those descriptors. See gRPC PR #141.

For a listener without TLS, list services with:

Health Checking

RoadRunner automatically registers a grpc.health.v1.Health service on the same gRPC listen port. This is the standard gRPC health checking protocol. No additional configuration is required.

Available methods

Method
Description

Check

Returns the current serving status of the server: SERVING or NOT_SERVING.

Watch

Opens a server-side stream that pushes status changes in real time.

List

Returns the health status of all registered services. Available since v2025.1.0 (requires grpc >= v1.72.0).

Lifecycle

When RoadRunner starts, the gRPC health service reports NOT_SERVING until workers are allocated and ready, then transitions to SERVING. On stop or reset the status reverts to NOT_SERVING.

Using grpc-health-probe

grpc-health-probe is a command-line tool commonly used as a Kubernetes health check for gRPC services.

If the server is healthy the tool exits with code 0; otherwise it exits with a non-zero code.

Example Kubernetes liveness probe:

For HTTP-based health checks (useful for load balancers and non-gRPC infrastructure), see the Health and Readiness checks page which documents the /health and /ready endpoints provided by the status plugin.

Full example of Configuration

Unix Socket

Configure optional mode, uid, and gid fields under grpc.unix_socket. See Unix socket attributes for their values. Keep the other gRPC settings from the preceding example:

Configure clients to use the same Unix socket. These settings apply to the listener socket. They were added in gRPC PR #154.

Connection age grace

max_connection_age_grace controls how long active RPCs can continue after the connection reaches max_connection_age. Zero or omitted grace means unlimited time. Set a finite grace to close the connection after that period.

The v5 plugin used max_connection_age as the grace period and ignored max_connection_age_grace. To preserve that behavior, explicitly set both values to the same duration.

Error details in logs

For a failed unary call, the grpc logger adds a details field when the error contains supported google.rpc.Status details. This field contains an array of type names and one-line message values. It is omitted when the error has no supported details.

The supported types from google/rpc/error_details.proto are BadRequest, ErrorInfo, DebugInfo, Help, LocalizedMessage, PreconditionFailure, QuotaFailure, RequestInfo, ResourceInfo, and RetryInfo. Other detail types are omitted.

Use a structured log mode to retain the field:

For example, a field validation error can include:

See logger configuration and gRPC PR #148.

OTLP support in the gRPC plugin

In the v2023.3.8 we added experimental support for the OTLP protocol in the gRPC plugin. Stable since v2024.1.1. To enable it, you need to activate otel plugin by adding the following lines to the .rr.yaml file:

Trace keys passed to the PHP workers are:

  1. Traceparent

  2. Uber-Trace-Id

Example:

More about OTLP plugin you may read here.

Common issues

  1. Registering two services with the same name is not allowed. GRPC server will panic after that.

Last updated

Was this helpful?