Service Providers
Services providers are plain JavaScript classes with lifecycle methods to perform actions during different phases of the application.
A service provider can register bindings into the container, extend existing bindings, or run actions after the HTTP server starts.
Service providers are the entry point to an AdonisJS application with the ability to modify the application state before it is considered ready.
The providers are registered inside the adonisrc.ts
file under the providers
array. The value is a function to lazily import the service provider
{
providers: [
() => import('@adonisjs/core/providers/app_provider'),
() => import('./providers/app_provider.js'),
]
}
By default, a provider is loaded in all the runtime environments. However, you can limit the provider to run in specific environments.
{
providers: [
() => import('@adonisjs/core/providers/app_provider'),
{
file: () => import('./providers/app_provider.js'),
environments: ['web', 'repl']
}
]
}
Writing service providers
Service providers are stored inside the providers
directory of your app. Alternatively, you can use the node ace make:provider app
command.
The provider module must have an export default
statement returning the provider class. The class constructor receives an instance of the Application class.
See also: Make provider command
import { ApplicationService } from '@adonisjs/core/types'
export default class AppProvider {
constructor(protected app: ApplicationService) {
}
}
Following are the lifecycle methods you can implement to perform different actions.
export default class AppProvider {
register() {
}
async boot() {
}
async start() {
}
async ready() {
}
async shutdown() {
}
}
register
The register
method is called after an instance of the provider class is created. The register
method can register bindings within the IoC container.
The register
method is synchronous, so you cannot use Promises inside this method.
export default class AppProvider {
register() {
this.app.container.bind('db', () => {
return new Database()
})
}
}
boot
The boot
method is called after all the bindings have been registered with the IoC container. Inside this method, you can resolve bindings from the container to extend/mutate them.
export default class AppProvider {
async boot() {
const validator = await this.app.container.make('validator')
// Add custom validation rules
validator.rule('foo', () => {})
}
}
It is a good practice to extend bindings when they are resolved from the container. For example, you can use the resolving
hook to add custom rules to the validator.
async boot() {
this.app.container.resolving('validator', (validator) => {
validator.rule('foo', () => {})
})
}
start
The start
method is called after the boot
and before the ready
method. It allows you to perform actions that the ready
hook actions might need.
ready
The ready
method gets called at different stages based on the application's environment.
web |
The ready method is called after the HTTP server has been started and is ready to accept requests. |
console |
The ready method is called just before the run method of the main command. |
test |
The ready method is called just before running all the tests. However, the test files are imported before the ready method. |
repl |
The ready method is called before the REPL prompt is displayed on the terminal. |
export default class AppProvider {
async start() {
if (this.app.getEnvironment() === 'web') {
}
if (this.app.getEnvironment() === 'console') {
}
if (this.app.getEnvironment() === 'test') {
}
if (this.app.getEnvironment() === 'repl') {
}
}
}
shutdown
The shutdown
method is called when AdonisJS is in the middle of gracefully exiting the application.
The event of exiting the application depends upon the environment in which the app is running and how the application process started. Please read the application lifecycle guide to know more about it.
export default class AppProvider {
async shutdown() {
// perform the cleanup
}
}