Overview
Before an Idylle application starts, it loads components in a specific order.
For each step, if a promise is returned, idylle will wait the Promise to be resolve to continue. If a Promise is rejected during the init process. The application won't start.
Going with the flow
By default Idylle will require
recursively all files in specific directories for each step.
Copy project_directory/
| actions/ <------- domain related functions, controllers, ...
| boot/ <------- database connections, fixtures, ...
| cache/ <------- cache system definition/initialization
| middlewares/ <------- generic middleware layers (body-parser, loggers, cors, mutler, ...)
| models/ <------- ORM/ODM models configuration
| routes/ <------- HTTP routing configuration
| settings/ <------- server configuration (port, tokens, secrets, hosts, ...)
It means you dont have anything to do except to put your files at the right place. Idylle will load each of them automatically.
As an example, an action with the path actions/users/create.js
will be available through app.actions.users.create()
Customizing the flow
For each step of the flow, you can subscribe to events to customize the behavior.
When you register one listener in the phase, you automatically disable the recursive require made by Idylle.
Note that you can subscribe multiple time to the same event if you want to split responsibilities.
1. The dependencies
Copy const Core = require ( 'idylle' ).Core;
const app = new Core ();
app
.on ( Core . events . init .dependencies , () => ({
errorHandler : require ( './myErrorHandler' ) ,
responseHandler : require ( './myResponseHandler' ) ,
criteriaBuilder : require ( './myCriteriaBuilder' )
}))
.start ();
module . exports = app;
Each of these dependencies will be used during the lifecycle of the application. To understand the responsibility of each of these components check CriteriaBuilder , ResponseHandler , ErrorHandler documentation.
2. The settings
The settings loading phase is the only step where the app object is not injected.
Copy const Core = require ( 'idylle' ).Core;
const app = new Core ();
app
.on ( Core . events . init .settings , settings => settings .port = 3000 )
.on ( Core . events . init .settings , settings => settings .secret = 's3cr3t' )
.start ();
module . exports = app;
When it comes to configure the server, you need to listen on a specific event Core.events.init.settings
.
3. The models
Copy const Core = require ( 'idylle' ).Core;
const app = new Core ();
const mongoose = require ( 'mongoose' );
app
.on ( Core . events . init .models , app => {
app .models = app .models || { noSQL : {} };
app . models . noSQL .User = mongoose .model ( 'User' , { login : String , password : String })
})
.start ();
module . exports = app;
Loading the models is associated to Core.events.init.models
.
4. The middlewares
Copy const Core = require ( 'idylle' ).Core;
const app = new Core ();
const bodyParser = require ( 'bodyParser' );
app
.on ( Core . events . init .middlewares , app => {
app .middlewares = app .middlewares || {};
app . middlewares .bodyParser = bodyParser
})
.start ();
module . exports = app;
Loading the middlewares is associated to Core.events.init.middlewares
.
5. The Actions
Copy const Core = require ( 'idylle' ).Core;
const app = new Core ();
app
.on ( Core . events . init .actions , app => {
app .actions = app .actions || {};
app . actions .users = require ( './actions/users' )(app);
})
.start ();
module . exports = app;
Loading the actions is associated to Core.events.init.actions
.
6. The Routes
Copy const Core = require ( 'idylle' ).Core;
const app = new Core ();
app
.on ( Core . events . init .routes , app => {
const router = app .Router ();
router
.get ( '/' , app . actions . users . list .expose ())
.post ( '/' ,
app . middlewares . bodyParser .json () ,
app . actions . users . create .expose ());
app . router .use ( `/api/users` , router);
})
.start ();
module . exports = app;
Loading the routes is associated to Core.events.init.routes
.
7. The Boot
Copy const Core = require ( 'idylle' ).Core;
const app = new Core ();
const mongoose = require ( 'mongoose' );
app
.on ( Core . events .booting , app => {
mongoose .connect ( app . settings . db .uri);
})
.start ();
module . exports = app;
Booting phase is associated to Core.events.booting
.
8. The Post Start
Copy const Core = require ( 'idylle' ).Core;
const app = new Core ();
app
.on ( Core . events . init .dependencies , () => ({ errorHandler : require ( './errors' ) }))
.on ( Core . events .started , app => console .log ( `API listening on port ${ app . settings .port } ` ))
.start ();
module . exports = app;