# The Flows

## Overview

Before an Idylle application starts, it loads components in a specific order.

![Illustration describing the full setup of an Idylle Application.](/files/-LBX89pHvXaAwjm9Nrap)

{% hint style="info" %}
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.
{% endhint %}

## Going with the flow

{% hint style="info" %}
By default Idylle will `require` **recursively** all files in specific directories for each step.
{% endhint %}

```
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.

{% hint style="danger" %}
When you register one listener in the phase, you automatically **disable** the recursive require made by Idylle.
{% endhint %}

{% hint style="info" %}
Note that you can subscribe multiple time to the same event if you want to split responsibilities.
{% endhint %}

### 1. The dependencies

```javascript
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](/idylle/core/concepts/criteriabuilder.md), [ResponseHandler](/idylle/core/concepts/responsehandler.md), [ErrorHandler](/idylle/core/concepts/responsehandler.md) documentation.

### 2. The settings

{% hint style="warning" %}
The settings loading phase is the only step where the app object is not injected.
{% endhint %}

```javascript
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

```javascript
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

```javascript
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

```javascript
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

```javascript
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

```javascript
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

```javascript
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;
�
```

Post start phase is associated to `Core.events.started`.

## Conclusion

As you can see it is very easy to customize the initialization of an Idylle application. Most of the time you will keep the default behavior, but since Idylle will require all the files in specific paths from the Node Working Directory (CWD), when you build a library with **Idylle**, you might want to explicitly load directories.

Examples : [Yemma](https://github.com/julien-sarazin/yemma), [Chappai](https://github.com/julien-sarazin/chappai)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://julien-sarazin.gitbook.io/idylle/core/the-flows.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
