# Asynchronous Message Bus (Gateways)

Asynchronous Message Buses let you make an entire Command or Event Bus asynchronous with a single configuration change, instead of annotating every handler individually.

**You'll know you need this when:**

* Your entire application should process commands in the background, not just individual handlers
* You're building a write API that accepts commands and queues all of them for async processing
* Adding `#[Asynchronous]` to every handler individually has become repetitive
* You need an Outbox pattern where events are committed as part of the same database transaction

{% hint style="success" %}
Asynchronous Gateways are available as part of **Ecotone Enterprise.**
{% endhint %}

## Asynchronous Gateways

To make Gateway Asynchronous we will use Asynchronous Attribute, just like with Asynchronous Message Handlers. We may can extend any types of Gateways: Command/Event/Query Buses, [Business Interfaces](/modelling/command-handling/business-interface.md) or custom [Gateways](/messaging/messaging-concepts/messaging-gateway.md).

To build for example a **CommandBus** which will send Messages over **async** channel, we will simply [extend a CommandBus interface](/modelling/extending-messaging-middlewares/extending-message-buses-gateways.md), and add our method.

```php
#[Asynchronous("async")]
interface AsynchronousCommandBus extends CommandBus
{

}
```

then we all Commands that will be triggered via **AsynchronousCommandBus** will go over async channel.

{% hint style="success" %}
It's enough to extend given **CommandBus** with custom interface to register new abstraction in Gateway in Dependency Container.
{% endhint %}

Having **asynchronous CommandBus** is especially useful, if given Message Handler is not meant be executed asynchronous by default.

```php
#[CommandHandler]
public function placeOrder(PlaceOrderCommand $command) : void
{
   // do something with $command
}
```

then when using standard CommandBus above Command Handler will be executed synchronous, when using AsynchronousCommandBus it will be done asynchronously.

## Outbox Event Bus

It's easy to build an Outbox pattern using this Asynchronous Gateways. Just make use of[ Dbal Message Channel](/modules/dbal-support.md) to push Messages over Database Channel.

```php
#[Asynchronous("outbox")]
interface OutboxEventBus extends EventBus {}
```

and then register dbal channel

```php
#[ServiceContext] 
public function orderChannel()
{
    return DbalBackedMessageChannelBuilder::create("orders");
}
```

Then whenever we will send Events within Command Handler (which is wrapped in transaction by default while using Dbal Module). Messages will be commited as part of same transaction.

```php
#[CommandHandler]
public function placeOrder(PlaceOrderCommand $command, OutboxEventBus $eventBus) : void
{
   // do something with $command
   
   $eventBus->publish(new OrderWasPlaced());
}
```


---

# Agent Instructions: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ecotone.tech/modelling/asynchronous-handling/asynchronous-message-bus-gateways.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
