> For the complete documentation index, see [llms.txt](https://docs.ecotone.tech/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ecotone.tech/messaging/conversion/conversion/headers-conversion.md).

# Headers Conversion

Converting message headers in Ecotone PHP

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.

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

This can be then accessed on the Message Handler level:

```php
#[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.

```php
#[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.

```php
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).

```php
$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.

```php
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.

```php
$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:

```php
/**
* @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](/messaging/conversion/conversion.md#media-type-converter) to deserialize it.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.ecotone.tech/messaging/conversion/conversion/headers-conversion.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
