Lifecycle and Hooks
Introduction
EzBackend's works by having modular hooks into the boot lifecycle of the app, allowing you to run any initialization code you need at any point of the boot lifecyle.
Boot order
Assuming the following hierarchy:
EzBackend
├─┬ child 1
| └── child 2
└── child 3
Lifecycle hooks are run in this order:
- All EzBackend
preInit
hooks - All child 1
preInit
hooks - All child 2
preInit
hooks - All child 3
preInit
hooks - All EzBackend
init
hooks - All child 1
init
hooks - And so on...
The available hooks are:
- preInit
- init
- postInit
- preHandler
- handler
- postHandler
- preRun
- run
- postRun
Sample Boot Cycle
You can print the boot lifecycle using:
- Sample
- Full Sample
async function main() {
await app.start()
console.log(app.prettyPrint())
}
main()
import {EzBackend, EzModel, Type} from '@ezbackend/common'
import { EzOpenAPI } from "@ezbackend/openapi";
import { EzDbUI } from "@ezbackend/db-ui";
import { EzCors } from "@ezbackend/cors";
const app = new EzBackend()
//---Plugins---
//Everything is an ezapp in ezbackend
app.addApp(new EzOpenAPI())
app.addApp(new EzDbUI())
app.addApp(new EzCors())
//---Plugins---
//Models are also ezapps in ezbackend
const model = new EzModel('ModelName', {
var1: Type.VARCHAR, //string
var2: Type.INT, //integer
})
app.addApp(model, { prefix: 'model-route-prefix' })
async function main() {
await app.start()
console.log(app.prettyPrint())
}
main()
The sample boot cycle for a default app is
bound root 217 ms
├─┬ _init 3 ms
│ ├── Create Entities Container 0 ms
│ └─┬ UnnamedApp4 1 ms
│ └── Create "ModelName" Entity 1 ms
├─┬ _postInit 38 ms
│ ├── Create Database Connection 36 ms
│ └─┬ UnnamedApp4 1 ms
│ └── Obtain ModelName Repository 0 ms
├─┬ _handler 17 ms
│ ├── Create Server Stub 1 ms
│ ├── Add Fastify Boom 0 ms
│ ├── Add Error Schema 0 ms
│ ├─┬ UnnamedApp1 1 ms
│ │ ├── Create Server Stub 0 ms
│ │ └── Add Swagger Plugin 0 ms
│ ├─┬ UnnamedApp2 4 ms
│ │ ├── Create Server Stub 0 ms
│ │ ├── Add DB-UI endpoint schemas 1 ms
│ │ ├── Serve UI Interface 0 ms
│ │ └─┬ DB-UI Endpoint Router 2 ms
│ │ ├── Create Server Stub 0 ms
│ │ └── Add DB-UI endpoints 1 ms
│ ├─┬ UnnamedApp3 3 ms
│ │ ├── Create Server Stub 0 ms
│ │ └── Add Cors Plugin 3 ms
│ └─┬ UnnamedApp4 6 ms
│ ├── Create Server Stub 0 ms
│ └─┬ router 5 ms
│ ├── Create Server Stub 0 ms
│ ├── Add Create Schema 1 ms
│ ├── Add Update Schema 0 ms
│ ├── Add Full Schema 0 ms
│ ├── Generate createOne route 0 ms
│ ├── Generate getOne route 0 ms
│ ├── Generate getAll route 0 ms
│ ├── Generate updateOne route 0 ms
│ └── Generate deleteOne route 0 ms
├─┬ _postHandler 27 ms
│ ├── Remove Server Stub 0 ms
│ ├── Create Fastify Server 20 ms
│ ├── Register Fastify Plugins 1 ms
│ ├─┬ UnnamedApp1 0 ms
│ │ └── Remove Server Stub 0 ms
│ ├─┬ UnnamedApp2 1 ms
│ │ ├── Remove Server Stub 0 ms
│ │ └─┬ DB-UI Endpoint Router 0 ms
│ │ └── Remove Server Stub 0 ms
│ ├─┬ UnnamedApp3 1 ms
│ │ └── Remove Server Stub 0 ms
│ └─┬ UnnamedApp4 1 ms
│ ├── Remove Server Stub 0 ms
│ └─┬ router 0 ms
│ └── Remove Server Stub 0 ms
├─┬ _run 123 ms
│ └── Run Fastify Server 123 ms
└─┬ _postRun 1 ms
└─┬ UnnamedApp2 1 ms
└── Display DB UI URL 0 ms
Adding hooks
We can add hooks in order to run different points in the lifecycle. For example, if we want a hook to print ---Systems Online---
after everything is loaded:
- Sample
- Full Sample
app.setPostRun("Print Systems Online", async(instance,opts) => {
console.log("---Systems Online---")
})
import {EzBackend, EzModel, Type} from '@ezbackend/common'
import { EzOpenAPI } from "@ezbackend/openapi";
import { EzDbUI } from "@ezbackend/db-ui";
import { EzCors } from "@ezbackend/cors";
const app = new EzBackend()
//---Plugins---
//Everything is an ezapp in ezbackend
app.addApp(new EzOpenAPI())
app.addApp(new EzDbUI())
app.addApp(new EzCors())
//---Plugins---
//Models are also ezapps in ezbackend
const model = new EzModel('ModelName', {
var1: Type.VARCHAR, //string
var2: Type.INT, //integer
})
app.addApp(model, { prefix: 'model-route-prefix' })
app.setPostRun("Print Systems Online", async(instance,opts) => {
console.log("---Systems Online---")
})
app.start()
Hook
Used to define the point in the lifecycle to add the hook
Example:
app.setInit(...)
app.setPostInit(...)
app.setPreInit(...)
Hook Name
Used during the pretty print to ensure future users understand what function is being run
Example:
app.setInit("My init hook",...)
app.setPostInit("My post init hook",...)
app.setPreInit("My pre init hook",...)
app.setPostRun("Print Systems Online",...)
Hook Function
The function used to alter the running instance, as well as the options supplied to it during app.start(opts)
app.setPostRun("Print Systems Online", async(instance,opts) => {
console.log("---Systems Online---")
})
Argument | Type | Description |
---|---|---|
instance | import {EzBackendInstance} from "@ezbackend/common" | Used to modify fastify, typeorm or any other objects in the instance |
opts | import {EzBackendOpts} from "@ezbackend/common" | Used to get a reference to the opts passed during app.start(opts) |
tip
You can see what is in the instance and opts using
app.setPostRun("View Instance and opts", async(instance,opts) => {
console.log(instance)
console.log(opts)
})
/>
warning
Take note of the boot order in order to ensure your hooks are running in the right order. You can check this with console.log(app.prettyPrint())
after await app.start
Removing Hooks
Removing hooks can be useful, for example if you wish to test EzBackend without running the server
app.removeHook("_run", "Run Fastify Server")
You can obtain the hook names from console.log(app.prettyPrint())
Core Module
@ezbackend/core
provides the core functionality for running the boot order in EzBackend. It is a thin wrapper around fastify's avvio
When you run import {App} from '@ezbackend/core
, there are no functions in the lifecycle
However, when you use import {EzBackend} from '@ezbackend/common
as a plugin, It comes with some lifecycle hooks in order to boot the application, as seen in the sample boot cycle