# Events

An event is a message emitted by the system when "something" happens. Again this could be a technical task being completed such as a **DatabaseBackedUp**, **LoadBalancerScaledOut** or as a result of changes in your business **CreditCardCharged**, **UserRegistered**, **PackageShipped**.

{% hint style="info" %}
Use natural language in the past-tense when naming an event since it represents a historic fact has taken place. This also helps improve the readability of your code, as the history of your application can be discussed in terms of the order of events.
{% endhint %}

### Creating an Event

Events are class definitions that extend from `Event`, eg:

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

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

  /**
   * 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

  /**
   * A credit card was successfully charged
   * @param creditCardToken Identifies the card that was charged
   * @param amount The amount, in USD, that the card was charged for
   */
  constructor (
    readonly creditCardToken: string,
    readonly amount: number
  ) {
  }
}
```

{% 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 %}

### Publishing an Event

Events can have 0-to-many different subscribers, who are generally interested in performing a next action as a result of the event being raised.

Use `.publish()` to publish an event:

```typescript
const creditCardCharged = new CreditCardCharged('abc', 123)

// Publish a message. All subscribers will receive a copy
await bus.publish(creditCardCharged)

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

### Handling an Event

Events 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 creditCardChargedHandler = handlerFor(
  CreditCardCharged,
  async (event: CreditCardCharged) => {
    // ...
  }
)
```

Implementing a class based handler

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

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

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()
```
