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.
Use plain english when naming commands. This helps understanding what a command will do once it's processed.
To implement a command, extend the Command class and add any relevant fields
1
import { Command } from '@node-ts/bus-messages'
2
​
3
export class ChargeCreditCard extends Command {
4
/**
5
* A unique name that identifies the message. This should be done in namespace style syntax,
6
* ie: organisation/domain/command-name
7
*/
8
$name = 'my-app/accounts/charge-credit-card'
9
​
10
/**
11
* The contract version of this message. This can be incremented if this message changes the
12
* number of properties etc to maintain backwards compatibility
13
*/
14
$version = 1
15
​
16
/**
17
* Create a charge on a credit card
18
* @param creditCardToken Identfies the card to charge
19
* @param amountThe amount, in USD, to charge the card
20
*/
21
constructor (
22
readonly creditCardToken: string,
23
readonly amount: number
24
) {
25
}
26
}
Copied!
A commands are sent to a single service for processing, and generally result in the publication of one or more events.
It's useful to declare all of your messages in a central package that can be shared amongst your publisher and subscriber services.

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:
1
const chargeCreditCard = new ChargeCreditCard('abc', 123)
2
​
3
// Send a command. This will be handled by a single subscriber
4
await bus.send(chargeCreditCard)
5
​
6
// Send a message along with a set of attributes
7
await bus.send(
8
chargeCreditCard,
9
{ correlationId: 'tok-1adsfas-df1' }
10
)
Copied!

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.
Implementing a function based handler
1
import { handlerFor } from '@node-ts/bus-core'
2
​
3
// Function based handler
4
const chargeCreditCardHandler = handlerFor(
5
ChargeCreditCard,
6
async (event: ChargeCreditCard) => {
7
// ...
8
}
9
)
Copied!
Implementing a class based handler
1
import { Handler } from '@node-ts/bus-core'
2
​
3
// Class based handler
4
class ChargeCreditCardHandler implements Handler<ChargeCreditCard> {
5
messageType = ChargeCreditCard
6
7
async handle (event: ChargeCreditCard) {
8
// ...
9
}
10
}
Copied!
Register the handler with the bus configuration
1
const bus = await Bus.configure()
2
.withHandler(chargeCreditCardHandler) // Function based handler
3
.withHandler(ChargeCreditCardHandler) // Class function based handler
4
.initialize()
Copied!
Remember to .start() the bus to start handling messages
1
await bus.start()
Copied!