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
import { Command } from'@node-ts/bus-messages'exportclassChargeCreditCardextendsCommand {/** * 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.
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:
constchargeCreditCard=newChargeCreditCard('abc',123)// Send a command. This will be handled by a single subscriberawaitbus.send(chargeCreditCard)// Send a message along with a set of attributesawaitbus.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.
Implementing a function based handler
import { handlerFor } from'@node-ts/bus-core'// Function based handlerconstchargeCreditCardHandler=handlerFor( ChargeCreditCard,async (event:ChargeCreditCard) => {// ... })
Implementing a class based handler
import { Handler } from'@node-ts/bus-core'// Class based handlerclassChargeCreditCardHandlerimplementsHandler<ChargeCreditCard> { messageType = ChargeCreditCardasynchandle (event:ChargeCreditCard) {// ... }}
Register the handler with the bus configuration
constbus=awaitBus.configure().withHandler(chargeCreditCardHandler) // Function based handler.withHandler(ChargeCreditCardHandler) // Class function based handler.initialize()
Remember to .start() the bus to start handling messages