overblog/thrift-bundle
Symfony bundle that integrates Apache Thrift, letting you expose and consume Thrift services with configurable protocols, transports, and serialization. Register services, clients, and servers as container services with flexible per-service configuration.
Check compatibility before you start. The latest release is 0.9.19, and its only change is a router fix for Symfony 3.4 — that tells you the maintained target is still the Symfony 3/4 bundle era (registered in AppKernel, not config/bundles.php). Verify the symfony/* constraints in its composer.json against your project; on Symfony 5+ expect to either bump constraints in a fork or pin older Symfony. The 0.9.x line is patch-only maintenance: assume no new features and no Symfony 5+/6+ support is coming. Treat it as "vendored code you own" rather than a maintained dependency.
Install the two hard prerequisites, not just the Composer package:
composer require overblog/thrift-bundle apache/thrift
# the Thrift IDL compiler must be on PATH — the bundle shells out to it
sudo apt-get install thrift-compiler # or: brew install thrift
thrift --version
The PHP runtime library (apache/thrift) and the compiler are separate things; the bundle needs both, and their versions must agree.
Register the bundle (new Overblog\ThriftBundle\OverblogThriftBundle() in AppKernel, or the equivalent in config/bundles.php), then look at the bundle's Resources/config and its DependencyInjection/Configuration.php first — that file is the authoritative list of config keys, and the README lags behind it. If you expose services, also check how the bundle wires its routing: 0.9.19 changed exactly that for Symfony 3.4, so on anything newer expect to patch the routing definition yourself.
Write one .thrift IDL and wire a single client. Minimal shape:
# config.yml
overblog_thrift:
clients:
blog:
service: BlogService
namespace: Overblog\Blog
options: { host: 127.0.0.1, port: 9090 }
idl:
- "@AppBundle/Resources/thrift/blog.thrift"
Generate, then inject. Run the bundle's Thrift compile/generate console command (list bin/console list thrift to find the exact name), clear the cache, and confirm the generated client appears as a container service. Your first end-to-end use case is: define a ping-style method in the IDL, generate, inject the client into a controller, and call it — that proves compiler, config, transport, and autoloading all line up before you build anything real.
IDL-first workflow. Treat .thrift files as the contract and keep them in a bundle's Resources/thrift/ (or a shared idl/ directory consumed by both client and server repos). Every change is: edit IDL → regenerate → commit generated classes or regenerate in CI. Don't hand-edit generated code; the bundle will overwrite it.
Client-as-service injection. The primary day-to-day pattern is that each configured client becomes a container service you type-hint or fetch by id. Inject it into controllers, console commands, and message handlers exactly like any other service:
public function __construct(BlogServiceClient $blog) { $this->blog = $blog; }
public function __invoke() { return $this->blog->getPost(42); }
Wrap it in a thin application-level adapter interface (BlogGateway) so your domain code doesn't depend on generated classes — this is also what makes it testable and lets you swap the implementation later.
Server side. For services you expose, implement the generated Iface/processor interface as a normal Symfony service, tag/register it per the bundle's server config, and run the bundle's server command (a long-running process — supervise it with systemd/supervisord, and restart on deploy). Keep handlers thin: resolve real services from the container inside the handler. Since 0.9.19 is purely a routing fix for Symfony 3.4, server-side route wiring is the one area you should verify manually after upgrading rather than assume.
Regenerate on deploy, never at runtime. Put the Thrift compile command in your build/deploy pipeline. Treat generated files as build artifacts (gitignore them or commit them consistently — pick one and enforce it).
Testing. Because the client is just a service, test against a stub of your adapter interface, or point the client at an in-process test server. For transport-level tests, spin up a real Thrift server in a fixture and hit it over loopback; do not mock the transport, it hides protocol problems.
Async/worker integration. Long-running workers are a natural fit: build the client once, reuse it, but be aware a dead socket needs reconnection logic — wrap calls in a retry that recreates the transport.
thrift 0.9 often won't run against apache/thrift 0.16 at runtime. Pin the compiler version in your Docker image and match the runtime library major/minor.composer dump-autoload. "Method not found" or "class not found" after a regen is almost always a stale cache or stale autoloader, not a config problem.namespace php ... line in the IDL and the namespace config key. A mismatch produces confusing "service not found" errors at container build time.composer.json constraints, fix deprecated DI APIs, patch the generator, and patch routing. Isolate it behind your own adapter so a future replacement (native apache/thrift wiring, gRPC, or plain HTTP) is a contained change.TException/TTransportException. Set explicit transport timeouts in options; the defaults can hang. Wrap every call site in a try/catch that distinguishes transport failures (retryable) from application exceptions (not).TBinaryProtocol + TSocket script outside Symfony and replay the call. If that works but the bundle doesn't, it's a DI/config issue; if both fail, it's server/protocol. For routing-specific problems on Symfony 4+, compare your route definitions against the 0.9.19 patch — that's the only part of the bundle that moved.services.yml to add logging, metrics, or connection pooling, and decorate the generated client service. That's usually cleaner than forking the bundle for small behavioral changes.host/port are passed through to the transport largely verbatim — check Configuration.php rather than assuming the README's key names, and remember YAML booleans (on, off, yes) silently coerce.How can I help you explore Laravel packages today?