# Commands

Commands are a type of message that represents an instruction to do work. These can be technical instructions such as **BackupDatabase**, **ScaleOutLoadBalancer** or modelled after your business domains like **PlaceOrder**, **ShipPackage**.

{% hint style="info" %}
Use plain english when naming commands. This helps understanding what a command will do once it's processed.
{% endhint %}

To implement a command, extend the `Command` class and add any relevant fields

```typescript
import { Command } from '@node-ts/bus-messages'

export class ChargeCreditCard extends Command {
  /**
   * A unique name that identifies the message. This should be done in namespace style syntax,
   * ie: organisation/domain/command-name
   */
  $name = 'my-app/accounts/charge-credit-card'

  /**
   * The contract version of this message. This can be incremented if this message changes the
   * number of properties etc to maintain backwards compatibility
   */
  $version = 1

  /**
   * Create a charge on a credit card
   * @param creditCardToken Identfies the card to charge
   * @param amountThe amount, in USD, to charge the card
   */
  constructor (
    readonly creditCardToken: string,
    readonly amount: number
  ) {
  }
}
```

A commands are sent to a single service for processing, and generally result in the publication of one or more [events](https://bus.node-ts.com/guide/messages/events).

{% hint style="info" %}
It's useful to declare all of your messages in a central package that can be shared amongst your publisher and subscriber services.
{% endhint %}

### Sending a command

Commands should only be processed by a single service, unlike events which may have multiple subscribers. Command processors usually receive a command, process it, and emit an event as a result of the operation completing.

Use `.send()` to send a command:

```typescript
const chargeCreditCard = new ChargeCreditCard('abc', 123)

// Send a command. This will be handled by a single subscriber
await bus.send(chargeCreditCard)

// Send a message along with a set of attributes
await bus.send(
  chargeCreditCard,
  { correlationId: 'tok-1adsfas-df1' }
)
```

### Handling a Command

Comments get processed by a **Handler**. This is a function or a class function that receives the message as a parameter and performs an operation. When the handler returns the message is deleted from the queue.&#x20;

Implementing a function based handler

```typescript
import { handlerFor } from '@node-ts/bus-core'

// Function based handler
const chargeCreditCardHandler = handlerFor(
  ChargeCreditCard,
  async (event: ChargeCreditCard) => {
    // ...
  }
)
```

Implementing a class based handler

```typescript
import { Handler } from '@node-ts/bus-core'

// Class based handler
class ChargeCreditCardHandler implements Handler<ChargeCreditCard> {
  messageType = ChargeCreditCard
  
  async handle (event: ChargeCreditCard) {
    // ...
  }
}
```

Register the handler with the bus configuration

```typescript
  const bus = await Bus.configure()
    .withHandler(chargeCreditCardHandler) // Function based handler
    .withHandler(ChargeCreditCardHandler) // Class function based handler
    .initialize()
```

Remember to `.start()` the bus to start handling messages

```typescript
await bus.start()
```
