packaged/thrift
Laravel package for generating and running Apache Thrift services. Provides artisan commands and tooling to compile IDL, organize generated PHP code, and integrate Thrift clients/servers into your app for fast, typed RPC between services.
Installation
composer require packaged/thrift
Ensure your system has the Thrift compiler (thrift) installed and in PATH.
Basic Usage
.thrift schema file (e.g., app/Contracts/User.thrift):
namespace php user
service UserService {
string getName(1: i32 userId)
}
thrift --gen php app/Contracts/User.thrift
use User\UserService\Client;
$transport = new THttpClient('http://thrift-server:8080');
$protocol = new TBinaryProtocol($transport);
$client = new Client($protocol);
$result = $client->getName(1); // Returns "John Doe"
First Use Case
Service-to-Service Communication
$transport = new TSocket('thrift-server', 9090);
$transport->open();
$protocol = new TBinaryProtocol($transport);
$client = new UserService\Client($protocol);
$result = $client->getName(1);
$transport->close();
TNonblockingSocket):
$socket = new TNonblockingSocket('thrift-server', 9090);
$client = new UserService\Client(new TBinaryProtocol($socket));
$client->getName(1, $result); // Non-blocking
Event-Driven Patterns
TProcessor to handle events in a Laravel queue worker:
$processor = new UserService\Processor(new UserServiceHandler());
$transport = new TServerTransport('0.0.0.0', 9090);
$server = new TServer($processor, $transport);
$server->serve(); // Run in a separate process (e.g., Laravel Horizon)
Data Serialization
$user = User::find(1);
$thriftUser = new UserService\User();
$thriftUser->setId($user->id);
$thriftUser->setName($user->name);
AppServiceProvider:
$this->app->singleton(UserService\Client::class, function ($app) {
$transport = new THttpClient(config('thrift.user_service_url'));
return new UserService\Client(new TBinaryProtocol($transport));
});
TTransport to inject headers:
class AuthenticatedTransport extends THttpClient {
public function __construct($url, $token) {
parent::__construct($url);
$this->setHeader('Authorization', 'Bearer ' . $token);
}
}
MockTransport for unit tests:
$mockTransport = new class extends TTransport {
public function read(...$args) { return 'mocked_response'; }
public function write(...$args) {}
};
$client = new UserService\Client(new TBinaryProtocol($mockTransport));
Schema Changes
optional fields and versioning:
struct User {
1: required i32 id,
2: optional string name, // Add new fields with higher IDs
3: optional string email // Versioned structs
}
Memory Leaks
$transport->close() or use try-finally:
try {
$transport->open();
// ...
} finally {
$transport->close();
}
TSocket/THttpClient objects instead of creating new ones per request.Protocol Mismatches
TBinaryProtocol). Mixing TCompactProtocol and TBinaryProtocol will fail silently.Laravel Caching
cache()->put('user', $thriftUser->toArray());
TTransport::setDebugOutput(true); // Logs raw Thrift traffic
9090 (default) to inspect binary payloads:
tshark -i any -Y "port 9090" -w thrift.pcap
TTransportException: Check if the server is running and the port is correct.TProtocolException: Schema mismatch (regenerate classes).TApplicationException: Invalid method calls (verify service contract).Custom Protocols
Extend TProtocol for domain-specific optimizations:
class CustomProtocol extends TBinaryProtocol {
public function writeString($str) {
// Custom compression logic
parent::writeString(gzcompress($str));
}
}
Laravel HTTP Client Integration
Wrap Thrift in a Laravel Macroable facade:
if (!Http::hasMacro('thrift')) {
Http::macro('thrift', function ($service, $method, $args) {
$client = app($service);
return $client->$method(...$args);
});
}
Usage:
$result = Http::thrift(UserService\Client::class, 'getName', [1]);
Thrift + Laravel Events Dispatch events when Thrift calls complete:
$client = new UserService\Client($protocol);
event(new ThriftCallStarted(UserService\Client::class, 'getName', [1]));
$result = $client->getName(1);
event(new ThriftCallCompleted(UserService\Client::class, 'getName', $result));
Performance Tuning
TTransport buffer for large payloads:
$socket = new TSocket('server', 9090);
$socket->setSendTimeout(5000); // 5s timeout
$socket->setRecvBuffer(1024 * 1024); // 1MB buffer
How can I help you explore Laravel packages today?