SlideShare a Scribd company logo
SymfonyD
a
y Chic
a
go 2025
Kris W
a
llsmith
UnleashthePowerof
SymfonyMessenger
Unleash the  Power  of Symfony Messenger
SymfonyD
a
y Chic
a
go 2025
Kris W
a
llsmith
UnleashthePowerof
SymfonyMessenger
AboutMe
• Former Symfony Core Team
• Live in Portland, Oregon
• VP of Engineering at Vacatia
• CTO at Pickathon Music Festival
• Likes long walks on the beach
Unleash the  Power  of Symfony Messenger
Reservations
TECH STACK
Owners & Contracts
Reservations
TECH STACK
Billing
Reservations
Owners & Contracts
TECH STACK
Billing
Reservations
Owners & Contracts
Integration Layer
TECH STACK
Symfony Messenger
Core Concepts
Message Bus
Wikipedi
a
: Bus (computing)
“A bus … is a communication system that
transfers data between components”
$envelope = $bus->dispatch($envelope);
Envelopes
class Envelope
{
function getMessage(): object;
function with(StampInterface ...$stamps): static;
function last(string $stampClass): ?StampInterface;
/** @return StampInterface[]|StampInterface[][] */
function all(?string $stampClass = null): array;
// ...
}
/** Stamps must be serializable value objects for transport. */
interface StampInterface {}
CoreConcepts
Symfony Messenger
• Message Bus
• Envelopes
• Messages
• Stamps
• …
What happens inside the bus?
Middleware
Component A Component B
Middleware
Component A Component B
Middleware
interface MiddlewareInterface
{
function handle(
Envelope $envelope,
StackInterface $stack,
): Envelope;
}
interface StackInterface
{
function next(): MiddlewareInterface;
}
class MyMiddleware implements MiddlewareInterface
{
public function handle(
Envelope $envelope,
StackInterface $stack,
): Envelope {
return $envelope;
}
}
class MyMiddleware implements MiddlewareInterface
{
public function handle(
Envelope $envelope,
StackInterface $stack,
): Envelope {
return $stack->next()->handle(
$envelope,
$stack,
);
}
}
public function handle(Envelope $envelope, StackInterface $stack): Envelope
{
// before
try {
$envelope = $stack->next()->handle($envelope, $stack);
} catch (Throwable $e) {
// on error
throw $e;
} finally {
// always
}
// on success
return $envelope;
}
CoreMiddleware
Symfony Messenger
• SendMessageMiddleware
• HandleMessageMiddleware
Transports
Transport
Worker
Send
Receive
CoreConcepts
Symfony Messenger
• Message Bus
• Envelopes
• Messages
• Stamps
• Middleware
• Transports (send & receive)
• Workers
• Handlers
Unleashed!
Billing
Reservations
Owners & Contracts
Integration Layer
TECH STACK
Billing
Reservations
Owners & Contracts
TECH STACK
“Porter”
readonly class IdStamp implements StampInterface
{
public function __construct(
public Ulid $id = new Ulid(),
) {}
}
class IdMiddleware implements MiddlewareInterface
{
public function handle(
Envelope $envelope,
StackInterface $stack,
): Envelope {
$envelope = $envelope->with(new IdStamp());
return $stack->next()->handle($envelope, $stack);
}
}
Transport
Worker
Send
Receive
Envelopes can pass through
middleware multiple times
class IdMiddleware implements MiddlewareInterface
{
public function handle(
Envelope $envelope,
StackInterface $stack,
): Envelope {
$envelope = $envelope->with(new IdStamp());
return $stack->next()->handle($envelope, $stack);
}
}
class IdMiddleware implements MiddlewareInterface
{
public function handle(
Envelope $envelope,
StackInterface $stack,
): Envelope {
if (!$envelope->last(IdStamp::class)) {
$envelope = $envelope->with(new IdStamp());
}
return $stack->next()->handle($envelope, $stack);
}
}
Now What?
Logging
class IdMiddleware implements MiddlewareInterface
{
public function __construct(
private IdContext $context,
) {}
public function handle(Envelope $envelope, StackInterface $stack): Envelope
{
if (!$stamp = $envelope->last(IdStamp::class)) {
$envelope = $envelope->with($stamp = new IdStamp());
}
$this->context->push($stamp->id);
try {
return $stack->next()->handle($envelope, $stack);
} finally {
$this->context->pop();
}
}
}
class IdProcessor implements ProcessorInterface
{
public function __construct(
private IdContext $context,
) {}
public function __invoke(LogRecord $record): LogRecord
{
if ($id = $this->context->head()) {
$record['extra']['message_id'] = "$id";
}
return $record;
}
}
public function handle(Envelope $envelope, StackInterface $stack): Envelope
{
if (!$stamp = $envelope->last(IdStamp::class)) {
$envelope = $envelope->with($stamp = new IdStamp());
$this->logDispatched($envelope);
}
$this->context->push($stamp->id);
try {
$envelope = $stack->next()->handle($envelope, $stack);
$envelope->last(HandledStamp::class) && $this->logHandled($envelope);
return $envelope;
} catch (Throwable $e) {
$this->logFailed($envelope, $e);
throw $e;
} finally {
$this->context->pop();
}
}
Nested Messages
Billing
Reservations
Owners & Contracts
“Porter”
TECH STACK
class Envelope
{
function with(StampInterface ...$stamps): static;
function last(string $stampClass): ?StampInterface;
/** @return StampInterface[]|StampInterface[][] */
function all(?string $stampClass = null): array;
// ...
}
public function handle(Envelope $envelope, StackInterface $stack): Envelope
{
if (!$envelope->last(IdStamp::class)) {
$envelope = $envelope->with(...array_map(
idToStamp(...),
$this->context->all(),
))->with(new IdStamp());
$this->logDispatched($envelope);
}
$this->context->push(array_map(
stampToId(...),
$envelope->all(IdStamp::class),
));
//...
}
CREATE TABLE messenger_log (
id CHAR(26) NOT NULL,
path JSON NOT NULL,
headers JSON,
body TEXT,
dispatched_at DATETIME NOT NULL,
handled_at DATETIME,
failed_at DATETIME,
error TEXT,
PRIMARY KEY (id)
)
Message Chains
Billing
Reservations
Owners & Contracts
“Porter”
TECH STACK
Create Reservation
Update Reservation
Update Guest
TECH STACK
Message Sequencing
class ChainStamp implements StampInterface
{
public function __construct(
public Envelope $envelope,
) {}
}
class ChainMiddleware implements MiddlewareInterface
{
public function handle(Envelope $envelope, StackInterface $stack): Envelope
{
$envelope = $stack->next()->handle($envelope, $stack);
if (!$envelope->last(HandledStamp::class)) {
return $envelope;
}
foreach ($envelope->all(ChainStamp::class) as $chainStamp) {
$this->bus->dispatch($chainStamp->envelope);
}
return $envelope->withoutAll(ChainStamp::class);
}
}
$bus->dispatch($createReservation, [
new ChainStamp($sendConfirmation),
]);
Message Dependencies
interface ChainInterface
{
function next(
object $handledMessage,
mixed $handledResult,
): ?object;
}
class UpdateReservation implements ChainInterface
{
public string $reservationId;
public function __construct(
public array $updates,
) {}
public function next(object $handledMessage, mixed $handledResult): ?object
{
$this->reservationId = $handledResult['id'];
return $this;
}
}
$bus->dispatch($createReservation, [
new ChainStamp($updateReservation),
]);
public function handle(
Envelope $envelope,
StackInterface $stack,
): Envelope {
// ...
foreach ($this->nextEnvelopes(
$envelope,
$handledStamp,
) as $nextEnvelope) {
$this->bus->dispatch($nextEnvelope);
}
// ...
}
private function nextEnvelopes(
Envelope $envelope,
HandledStamp $handledStamp,
): iterable {
foreach ($envelope->all(ChainStamp::class) as $chainStamp) {
$nextMessage = $chainStamp->envelope->getMessage();
if (!$nextMessage instanceof ChainInterface) {
yield $chainStamp->envelope;
} elseif ($nextMessage = $nextMessage->chain(
$envelope->getMessage(),
$handledStamp->getResult(),
)) {
yield Envelope::wrap($nextMessage);
}
}
}
UnleashthePowerofSymfonyMessenger
• Message Bus
• Envelopes
• Messages
• Stamps
• Middleware
• Transports (send & receive)
• Workers
• Handlers
• Message IDs
• Message Log
• Nested Messages
• Message Sequencing
• Message Dependencies
SymfonyD
a
y Chic
a
go 2025
Thank you!

More Related Content

ODP
Groovy Ast Transformations (greach)
PPTX
ES6 is Nigh
PDF
Type safe embedded domain-specific languages
PDF
Design Patterns avec PHP 5.3, Symfony et Pimple
PDF
Functional Scala 2020
PDF
PDF
Emerging Languages: A Tour of the Horizon
PDF
Pim Elshoff "Technically DDD"
Groovy Ast Transformations (greach)
ES6 is Nigh
Type safe embedded domain-specific languages
Design Patterns avec PHP 5.3, Symfony et Pimple
Functional Scala 2020
Emerging Languages: A Tour of the Horizon
Pim Elshoff "Technically DDD"

Similar to Unleash the Power of Symfony Messenger (20)

PDF
How Kris Writes Symfony Apps
PDF
Best practices for crafting high quality PHP apps (Bulgaria 2019)
ODP
AST Transformations at JFokus
PPTX
“SOLID principles in PHP – how to apply them in PHP and why should we care“ b...
KEY
ODP
AST Transformations
PDF
TypeScript Introduction
PDF
Functional programming using underscorejs
PDF
XQuery Rocks
PDF
News of the Symfony2 World
PPTX
Dartprogramming
PDF
Crafting Quality PHP Applications (Bucharest Tech Week 2017)
PDF
Absolute Beginners Guide to Puppet Through Types - PuppetConf 2014
KEY
Symfony2 Building on Alpha / Beta technology
ODP
Ast transformations
PDF
The IoC Hydra - Dutch PHP Conference 2016
PDF
Practical Event Sourcing
KEY
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
PDF
Symfony components in the wild, PHPNW12
PDF
The state of your own hypertext preprocessor
How Kris Writes Symfony Apps
Best practices for crafting high quality PHP apps (Bulgaria 2019)
AST Transformations at JFokus
“SOLID principles in PHP – how to apply them in PHP and why should we care“ b...
AST Transformations
TypeScript Introduction
Functional programming using underscorejs
XQuery Rocks
News of the Symfony2 World
Dartprogramming
Crafting Quality PHP Applications (Bucharest Tech Week 2017)
Absolute Beginners Guide to Puppet Through Types - PuppetConf 2014
Symfony2 Building on Alpha / Beta technology
Ast transformations
The IoC Hydra - Dutch PHP Conference 2016
Practical Event Sourcing
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Symfony components in the wild, PHPNW12
The state of your own hypertext preprocessor
Ad

More from Kris Wallsmith (16)

PDF
Matters of State
PDF
The View From Inside
PDF
How kris-writes-symfony-apps-london
PDF
Drupal, meet Assetic
PDF
How Kris Writes Symfony Apps
PDF
Love and Loss: A Symfony Security Play
PDF
Assetic (Zendcon)
PDF
Assetic (OSCON)
PDF
Assetic (Symfony Live Paris)
PDF
Introducing Assetic (NYPHP)
PDF
Introducing Assetic: Asset Management for PHP 5.3
PDF
Doctrine MongoDB ODM (PDXPHP)
PDF
Advanced symfony Techniques
PDF
A Practical Introduction to Symfony2
PDF
Symfony 2
PDF
Symfony in the Cloud
Matters of State
The View From Inside
How kris-writes-symfony-apps-london
Drupal, meet Assetic
How Kris Writes Symfony Apps
Love and Loss: A Symfony Security Play
Assetic (Zendcon)
Assetic (OSCON)
Assetic (Symfony Live Paris)
Introducing Assetic (NYPHP)
Introducing Assetic: Asset Management for PHP 5.3
Doctrine MongoDB ODM (PDXPHP)
Advanced symfony Techniques
A Practical Introduction to Symfony2
Symfony 2
Symfony in the Cloud
Ad

Recently uploaded (20)

PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PPTX
MYSQL Presentation for SQL database connectivity
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
cuic standard and advanced reporting.pdf
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
Network Security Unit 5.pdf for BCA BBA.
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PDF
NewMind AI Monthly Chronicles - July 2025
PDF
KodekX | Application Modernization Development
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
Electronic commerce courselecture one. Pdf
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
MYSQL Presentation for SQL database connectivity
Digital-Transformation-Roadmap-for-Companies.pptx
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Unlocking AI with Model Context Protocol (MCP)
cuic standard and advanced reporting.pdf
Review of recent advances in non-invasive hemoglobin estimation
Network Security Unit 5.pdf for BCA BBA.
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Understanding_Digital_Forensics_Presentation.pptx
NewMind AI Monthly Chronicles - July 2025
KodekX | Application Modernization Development
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Diabetes mellitus diagnosis method based random forest with bat algorithm
Reach Out and Touch Someone: Haptics and Empathic Computing
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
The AUB Centre for AI in Media Proposal.docx
Electronic commerce courselecture one. Pdf

Unleash the Power of Symfony Messenger