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


---

# 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://bus.node-ts.com/guide/messages/events.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.
