Headers Conversion

Ecotone allows for serialization of Message Headers before they go the Message Channel (Queue).

Scalar Headers

When we are sending Message Headers as simple scalar types like string or integer, then no Conversion is needed. In those situations Message Headers will be passed as they are.

// execution
$commandBus->send(
   $command,
   metadata: [
      'executorId' => '1234'
   ]
)

This can be then accessed on the Message Handler level:

#[Asynchronous('async')]
#[CommandHandler]
public function placeOrder(
   PlaceOrderCommand $command,
   #[Header('executorId')] string $executorId
)
{
   // do something
}

Converting Scalars on the Message Endpoint

Even so if Header was sent as scalar, we still can convert it to Application specific object on the Message Handler level.

#[Asynchronous('async')]
#[CommandHandler]
public function placeOrder(
   PlaceOrderCommand $command,
   #[Header('executorId')] ExecutorId $executorId
)
{
   // do something
}

For this we do need a Converter, which will state how given Class should be deserialized from string to ExecutorId object.

class ExampleConverterService
{
    #[Converter] 
    public function convert(string $data) : ExecutorId
    {
        return ExecutorId::fromString($data);
    }
}

Class Headers

We may actually want to pass Headers in more meaningful representation than simple scalars and let Ecotone do serialization when given Message goes to Message Channel (Queue).

$commandBus->send(
   $command,
   metadata: [
      'executorId' => ExecutorId::fromString('1234')
   ]
)

For this we need Conversion from ExecutorId to string, for Ecotone to know how to serialize it before it will go to Asynchronous Channel.

class ExampleConverterService
{
    #[Converter] 
    public function convert(ExecutorId $data) : string
    {
        return $data->toString();
    }
}

Dealing with Collections

There may be cases, when simple PHP to PHP Conversion will not be enough. This may be for example, when we will be dealing with Collection of Classes.

$commandBus->send(
   $command,
   metadata: [
      'types' => [
         OrderType::fromString('quick-delivery'),
         OrderType::fromString('promotion'),
      ]
   ]
)

In those cases Ecotone will fallback to serialize Message Header to JSON. This way we can serialize even most complex Headers.

Then on the receiving side:

/**
* @param OrderType[] $types
*/
#[Asynchronous('async')]
#[CommandHandler]
public function placeOrder(
   PlaceOrderCommand $command,
   #[Header('types')] array $types
)
{
   // do something
}

Actually the Docblock is crucial here, as it tell Ecotone what Collection type we are dealing with. This way Ecotone will be able to pass is to your defined Media Type Converter to deserialize it.

Last updated