Events (Hooks)
Overview
Events (or hooks) are a way to listen and react to the application's lifecycle events, and are used mostly to setup, teardown, and manage resources.
Sodacore Application Lifecycle
Below is a rough diagram of the Sodacore application lifecycle:
null
The Sodacore application's lifecycle is pretty simple and as follows:
- Construct: Firstly we initialise the configuration, and prepare a logger either by a passed in config option or use the built in.
- We then register all of this with the Registry so everything else can access it.
- We initialise the core modules of the application, like: autowire, task runner, services, etc.
- We setup any process signal listeners.
- We then call app.start which will firstly start the initialisation sequence.
- This will tell the autowire to find all the modules and register them with the Registry.
- We then initialise the events, and fire the
preInit
event. - We then call init against all the modules, services, task runners, etc.
- We then fire the
postInit
and then thepreStart
event. - We then start the modules, services, task runners, etc.
- This will fire up any services like HTTP servers, etc, and at the point the application is running.
- If the application throws an error, or the user closes it, we shall set an interval to force the process to stay open.
- We then trigger the
preStop
event. - We shutdown all the modules, services, etc.
- We then trigger the
postStop
event. - And then the application exits.
Usage
The @sodacore/core
package provides a simple hook decorator that allows you to define and listen to events, and these hooks can be placed on pretty much any module, controllers, services, providers, etc.
To create a hook, let's assume we have a provider that needs to populate a list of countries, we can do this like so:
typescript
import { Provider } from '@sodacore/di';
import { Hook } from '@sodacore/core';
@Provide()
export class CountryProvider {
private countries: string[] = [];
@Hook('preInit')
public async init() {
const response = await fetch('https://restcountries.com/v3.1/all');
const data = await response.json();
this.countries = data.map((country: any) => country.name.common);
}
}
The above code does the following:
- We create a new class called
CountryProvider
. - We use the
@Provide
decorator to tell the framework that this is a provider. - We create a private property called
countries
and set it to an empty array. - We use the
@Hook
decorator to tell the framework that this method should be called when thepreInit
event is fired. - When the method is called, we shall fetch a list of countries from a public API and then map the response to just the country names.
Available Events
The following events are available to listen to:
Event Name | Description |
---|---|
preInit | This event is fired before the application is initialised. |
postInit | This event is fired after the application is initialised. |
preStart | This event is fired before the application is started. |
postStart | This event is fired after the application is started. |
preStop | This event is fired before the application is stopped. |
postStop | This event is fired just before the application exits. |