Using server side events
Apostrophe emits many sever-side events to allow project code and installed modules to respond as needed. These range from start-up events to events triggered by normal editor actions. For example, if we had a website to track ghost sightings, we could watch for new sighting submissions and respond by sending the location address to a mapping API for validation and additional location information.
For a list of server-side events, see the events reference page.
The handlers
module property
Apostrophe modules have a dedicated function property to register event handlers. As a reminder, essentially all code in Apostrophe projects is a part of one module or another, whether custom or configuration of an installed module (including core modules).
Any module can include a handlers
customization function, which takes the module itself as an argument. This function returns an object whose keys are names of server-side events. Those event keys are assigned an object containing event handlers.
Every event includes particular arguments, so event handlers need to be written with matching parameters. For example, the beforeInsert
event from piece type modules includes the request (req
) and an object of data for the inserted piece (piece
).
The examples below show two examples of how a custom product
module registers event handlers for that event.
The first event handler object is set to watch beforeInsert
. Since that key only includes the event name it will watch for the event only when emitted by this product
module.
The second event handler object is set to the key '@apostrophecms/piece-type:beforeInsert'
. This still watches the beforeInsert
event, but since it begins with a module name, @apostrophecms/piece-type
followed by a colon, it will run the handler whenever that module, or any modules that extend it, emit that event. Since all piece types extend that named module, this handler will run before any piece is inserted into the database.
Multiple handlers for an event
Event handlers can be spread across multiple modules in a project even if they respond to the same event. This allows us to keep each handler in the module that is most related to their purpose. When a product is updated by an editor, one module may send emails to notify the sales team and another module may apply sales tax to the product's price.
At the same time, multiple event handlers for a single event can be included in a single module. Each handler should be added as a separate property of the event object. This allows us to avoid having only one large handler that might get hard to maintain.
INFO
Event handler names are important (e.g., applyTax
and emailSales
in the example above). They are used in log messages to help us find the source of problems, for one reason. They also allow us to override or extend an event handler when inherited by another module. Name them well and use multiple handlers to make the code easier to maintain.