Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Roadrunner Grpc Laravel Package

spiral/roadrunner-grpc

Laravel-friendly integration for RoadRunner gRPC: run high-performance PHP gRPC servers/workers, handle protobuf-based services, and communicate with the RoadRunner runtime for fast, long-lived processes and efficient microservices.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Installation:

    composer require spiral/roadrunner-grpc
    

    Ensure RoadRunner is installed (roadrunner --version) and configured with the gRPC plugin.

  2. Configure RoadRunner (rr.yaml):

    version: '3'
    grpc:
      active: true
      workers:
        command: 'php public/grpc_server.php'
        pool:
          numWorkers: 4
    
  3. Define a .proto file (e.g., proto/hello.proto):

    syntax = "proto3";
    service HelloService {
      rpc SayHello (HelloRequest) returns (HelloResponse);
    }
    message HelloRequest { string name = 1; }
    message HelloResponse { string message = 1; }
    
  4. Generate PHP stubs:

    protoc --php_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_php_plugin` proto/hello.proto
    
  5. Implement the service (app/Services/HelloService.php):

    use Generated\HelloServiceInterface;
    
    class HelloService implements HelloServiceInterface {
        public function sayHello($request, ServerInterface $server = null) {
            return new HelloResponse(['message' => "Hello, {$request->getName()}"]);
        }
    }
    
  6. Bootstrap the gRPC server (public/grpc_server.php):

    require __DIR__.'/../vendor/autoload.php';
    $worker = new \Spiral\RoadRunner\GRPC\Worker(new \Spiral\RoadRunner\GRPC\Invoker());
    $worker->run();
    
  7. Start RoadRunner:

    rr serve
    

Implementation Patterns

Service Layer Integration

  • Dependency Injection: Use Laravel’s service container to resolve dependencies in gRPC handlers:

    $container = new \Illuminate\Container\Container();
    $container->singleton(\App\Services\HelloService::class);
    $worker = new \Spiral\RoadRunner\GRPC\Worker(
        new \Spiral\RoadRunner\GRPC\Invoker($container)
    );
    
  • Middleware Pipeline: Wrap handlers with middleware (e.g., auth, logging):

    $worker = new \Spiral\RoadRunner\GRPC\Worker(
        new \Spiral\RoadRunner\GRPC\Invoker($container),
        new \Spiral\RoadRunner\GRPC\Middleware\AuthMiddleware()
    );
    

Streaming RPCs

  • Server-Side Streaming:

    public function streamData($request, ServerInterface $server) {
        $stream = $server->write(new DataResponse(['data' => 'chunk1']));
        yield $stream;
        $stream->write(new DataResponse(['data' => 'chunk2']));
    }
    
  • Bidirectional Streaming: Use ServerStreamInterface to read client streams:

    public function bidirectionalStream(ServerStreamInterface $stream) {
        foreach ($stream as $chunk) {
            // Process chunk
        }
    }
    

Error Handling

  • Convert PHP Exceptions to gRPC Status Codes:

    try {
        return $this->service->execute($request);
    } catch (\InvalidArgumentException $e) {
        throw new \Grpc\RpcException(
            new \Google\Protobuf\Internal\RepeatedField(),
            \Grpc\Status::INVALID_ARGUMENT,
            $e->getMessage()
        );
    }
    
  • Custom Metadata: Attach debug info to responses:

    $response = new HelloResponse(['message' => 'Hello']);
    $response->setMetadata(['trace_id' => \Illuminate\Support\Str::uuid()]);
    return $response;
    

Protobuf Versioning

  • Backward Compatibility: Use oneof and optional fields to avoid breaking changes:

    message User {
        oneof user_data {
            string email = 1;
            string phone = 2;
        }
    }
    
  • Code Generation: Re-generate stubs after .proto changes:

    protoc --php_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_php_plugin` --proto_path=proto proto/*.proto
    

Gotchas and Tips

Debugging

  • Worker Logs: Check RoadRunner’s worker logs (rr logs) for silent failures. Use monolog for structured logging:

    $logger = new \Monolog\Logger('grpc');
    $logger->pushHandler(new \Monolog\Handler\StreamHandler('php://stderr'));
    $worker = new \Spiral\RoadRunner\GRPC\Worker($invoker, $logger);
    
  • gRPC CLI Tools: Test locally with grpcurl:

    grpcurl -plaintext -d '{"name":"World"}' localhost:6001 app.HelloService/SayHello
    

Performance

  • Worker Pool Tuning: Adjust numWorkers and maxJobs in rr.yaml based on load:

    grpc:
      workers:
        pool:
          numWorkers: 8       # Match CPU cores
          maxJobs: 5000       # Avoid queue starvation
    
  • Protobuf Optimization: Use optimize_for = CODE_SIZE in .proto for smaller payloads.

Laravel-Specific Quirks

  • Service Container: Avoid circular dependencies by resolving gRPC services after Laravel’s bootstrapping:

    $app = require __DIR__.'/../bootstrap/app.php';
    $app->make(\Spiral\RoadRunner\GRPC\Invoker::class)->run();
    
  • Shared State: Use Spiral\RoadRunner\GRPC\ContextInterface for request-scoped data:

    $context = new \Spiral\RoadRunner\GRPC\Context();
    $context->withValue('user_id', auth()->id());
    $worker->run($context);
    

Common Pitfalls

  1. Stub Autoloading: Generated classes must be in vendor/ or manually autoloaded. Add to composer.json:

    "autoload": {
        "files": ["generated/*.php"]
    }
    
  2. TLS Misconfiguration: Ensure rr.yaml includes TLS settings:

    grpc:
      tls:
        cert: /path/to/cert.pem
        key: /path/to/key.pem
    
  3. Protobuf Namespace Collisions: Use option php_namespace = "Generated"; in .proto to avoid conflicts with Laravel classes.

  4. PHP 8.4 Deprecations: Explicitly typehint array as array<string, mixed> to avoid warnings:

    public function handle(array $request): array {
        return ['data' => $request['input']];
    }
    
  5. RoadRunner Version Mismatch: Pin spiral/roadrunner to a compatible version (e.g., ^2024 for RR 2024.x). Check release notes for breaking changes.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codraw/entity-migrator
codraw/doctrine-extra
codraw/aws-tool-kit
codraw/validator
codraw/workflow
codraw/open-api
codraw/cron-job
codraw/process
codraw/log
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony