# 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](https://docs.ecotone.tech/modelling/command-handling/business-interface) or custom [Gateways](https://docs.ecotone.tech/messaging/messaging-concepts/messaging-gateway).

To build for example a **CommandBus** which will send Messages over **async** channel, we will simply [extend a CommandBus interface](https://docs.ecotone.tech/modelling/extending-messaging-middlewares/extending-message-buses-gateways), 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](https://docs.ecotone.tech/modules/dbal-support) 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());
}
```
