folk-plugin-grpc
gRPC plugin for Folk — unary call passthrough to PHP workers via tonic. No Rust protobuf codegen required.
Status: in active development. See folk-spec for the roadmap.
Requirements
- Rust 1.85+
- folk-api
- PHP with
google/protobufor theprotobufPECL extension
Installation
# Cargo.toml
= "0.1"
Quick start
Add to folk.build.toml:
[[]]
= "folk-plugin-grpc"
= "0.1"
= "grpc"
Configure in folk.toml:
[]
= "0.0.0.0:50051"
= false
Write a PHP gRPC service class:
Register in the worker entry point:
Test with grpcurl:
# helloworld.Greeter
# { "message": "Hello, Folk" }
Configuration
| Key | Type | Default | Description |
|---|---|---|---|
listen |
SocketAddr |
"0.0.0.0:50051" |
Address and port for the gRPC server. |
reflection |
bool |
false |
Enable gRPC server reflection (for grpcurl/Postman discovery). |
How it works
Passthrough model
The key design decision: Rust does not decode or encode protobuf messages. It treats protobuf payloads as opaque bytes. PHP handles all protobuf serialization using its own generated classes.
This means:
- No
.protofiles needed at build time in Rust. - No protobuf codegen step in the Rust build.
- PHP owns the service contract entirely.
- Adding or changing protobuf services requires no Rust recompilation.
Request flow
- A gRPC client sends an HTTP/2 request to
/{ServiceName}/{MethodName}. - The plugin extracts the service and method names from the URI path.
- The 5-byte gRPC framing (compression flag + length prefix) is stripped.
- The raw protobuf bytes are wrapped in a
GrpcEnvelope:{ service: "helloworld.Greeter", method: "SayHello", payload: <bytes> } - The envelope is serialized to MessagePack and sent to a PHP worker via
executor.execute(). - The PHP worker decodes protobuf, executes logic, and returns serialized protobuf bytes.
- The plugin re-applies gRPC framing and returns the response.
Error handling
- Bad path format → gRPC status
UNIMPLEMENTED(12) - Body read failure → gRPC status
INTERNAL(13) - Worker execution error → gRPC status
INTERNAL(13)
RPC method
grpc.services — Lists registered gRPC service names via the admin socket.
License
MIT