# Blueprint Developer Guide

Learn to develop using the Blueprint framework


# Quick Start

Learn how to get started with Blueprint


# Getting Started

Instructions to get you up and running in seconds

## Installation

First, install [blueprint-cli](https://github.com/onehilltech/blueprint-cli) globally.

```bash
npm install -g @onehilltech/blueprint-cli
```

The [command-line interface (cli)](/developer-guide/untitled-2) is used to create a new Blueprint application, and manage the application's project space.

## Creating an Application

Use the installed cli to generate a new application.

```bash
blueprint new helloworld
```

The cli will generate a new Blueprint application in the `helloworld` directory. It will also install the node modules for the application.

## Running the Application

Run the Blueprint application by simply running [NodeJS](https://nodejs.org/en/) from the root directory of your application.

```bash
cd ./helloworld
node ./app
```

The Blueprint application will launch with the default configuration. You can now open a browser to <http://localhost:8080>, and see the quick start Blueprint application.


# My First Application

Simple tutorial for creating your first Blueprint application

In this tutorial, you will create your first Blueprint application. We will adopt the [super-rentals tutorial from EmberJS](https://guides.emberjs.com/release/tutorial/ember-cli/) by replacing the [mirage segment of the original tutorial](https://guides.emberjs.com/release/tutorial/installing-addons/#toc_ember-cli-mirage) with a Blueprint application. If you implement the original EmberJS tutorial, then you will be able to populate the EmberJS application with data from an Application Programming Interface (API) server (*i.e.*, the Blueprint application).

At the end of this tutorial, you will have experience with the following concepts:

* [Creating a Blueprint application](/quick-start/my-first-application/create-your-application)
* [Implementing a controller](/quick-start/my-first-application/controllers)
* [Defining a route](/quick-start/my-first-application/routers-and-routes)
* [Implementing a service](/quick-start/my-first-application/services)
* [Implementing a resource controller](/quick-start/my-first-application/resources-and-resource-controllers)
* [Validating and sanitizing input](/quick-start/my-first-application/validating-and-sanitizing-input)
* [Unit testing your application](/quick-start/my-first-application/unit-testing-your-application)
* [Using policies in your application](/quick-start/my-first-application/policies)


# Creating Your Application

## Generating your Application

First, we need to [install the Blueprint command-line interface (cli)](/quick-start/getting-started#installation). The cli makes it easier to start a new Blueprint application, and implement different components of the application. When installing the cli, you want to install it globally.

Now, use the installed [blueprint cli](https://github.com/onehilltech/blueprint-cli/) to generate a new application.

```bash
blueprint new super-rentals
```

The cli will generate a new Blueprint application in the `super-rentals` directory. It will also install the node modules for the application.&#x20;

## Starting your application

Let's make sure the `super-rentals`  application generated correctly. Change to the newly generated directory, and run the application as follows:

```bash
node ./app
```

This will start the Blueprint application in development mode, and make it available at <http://localhost:5000>.

If you want to run the Blueprint application in a different environment mode, then use the `NODE_ENV` environment variable. For example, if you want to run the application in a `production` environment, then use the following command:

```bash
NODE_ENV=production node ./app
```


# Controllers

## Generating Your Controller

Now that we have created our application, our next step is to create our controllers. Controllers define the business-logic of the Blueprint application, and are a composed from group of actions. The actions of a controller are responsible for servicing requests from clients.&#x20;

If we look at the original [super-rentals tutorial](https://guides.emberjs.com/release/tutorial/installing-addons/#toc_ember-cli-mirage), the mirage component of the tutorial defines the single route `GET /api/rentals`. This means that we need an action to handle this HTTP request from the client.

First, let's define our controller. We are going to name the controller `rental` since it will be responsible for all business logic related to rentals.

```bash
blueprint generate controller rental
```

{% hint style="info" %}
Make sure you run the Blueprint cli from the Blueprint application directory. In this tutorial, you must run the Blueprint cli from the `./super-rentals` directory.
{% endhint %}

This command will generate an empty controller (*i.e.*, a controller with no actions) named `rental` in the `./app/controllers` directory.

{% code title="app/controllers/rental.js" %}

```javascript
const {
  Controller,
  Action
} = require ('@onehilltech/blueprint');

/**
 * @class rental
 */
module.exports = Controller.extend ({
})
```

{% endcode %}

## Implementing the Action

We can now add our single action to the `rental` controller that will get the rentals when requested by a client. The action we create will return the [same data as the EmberJS super-rentals example](https://guides.emberjs.com/release/tutorial/installing-addons/#toc_ember-cli-mirage).

{% code title="app/controllers/rental.js" %}

```javascript
const {
  Controller,
  Action
} = require ('@onehilltech/blueprint');

/**
 * @class rental
 */
module.exports = Controller.extend ({
  get () {
    return Action.extend ({
      /**
       * The execute(res, res) method is an abstract method that must be 
       * implemented by all Action subclasses. The execute(req, res) method
       * is responsible for handling the request by sending a response to
       * the client.       
       */
      execute (req, res) {
        res.status (200).json ({
          data: [
            {
              type: 'rentals',
              id: 'grand-old-mansion',
              attributes: {
                title: 'Grand Old Mansion',
                owner: 'Veruca Salt',
                city: 'San Francisco',
                category: 'Estate',
                bedrooms: 15,
                image: 'https://upload.wikimedia.org/wikipedia/commons/c/cb/Crane_estate_(5).jpg'
              }
            },
            {
              type: 'rentals',
              id: 'urban-living',
              attributes: {
                title: 'Urban Living',
                owner: 'Mike Teavee',
                city: 'Seattle',
                category: 'Condo',
                bedrooms: 1,
                image: 'https://upload.wikimedia.org/wikipedia/commons/0/0e/Alfonso_13_Highrise_Tegucigalpa.jpg'
              }
            },
            {
              type: 'rentals',
              id: 'downtown-charm',
              attributes: {
                title: 'Downtown Charm',
                owner: 'Violet Beauregarde',
                city: 'Portland',
                category: 'Apartment',
                bedrooms: 3,
                image: 'https://upload.wikimedia.org/wikipedia/commons/f/f7/Wheeldon_Apartment_Building_-_Portland_Oregon.jpg'
              }
            }]
        });
      }
    })
  }
});
```

{% endcode %}

That was quite simple!

## Next Steps

Now we have a controller that defines an action to respond to client requests for rentals.� Our next step is to define a route that invokes this action.


# Routers & Routes

We have[ implemented a controller](/quick-start/my-first-application/controllers) with a single action that returns a list of rentals. The controller and its actions by itself cannot handle requests. It is not until we bind a controller's action with a route are we able to handle requests from client.

The route serves as the public facing access point to the Blueprint application. The route is consists of an HTTP verb (*e.g.*, `GET`, `DELETE`, `POST`,  and `PUT`) and a path (*e.g.*, `/a/b/c`). In the super-rentals example, there is the single route `GET /api/rentals`. Because we want our Blueprint application to serve as the API service for the super-rentals example, we need our application to define the same route as expect by the EmberJS application.

## Defining Your Router

All routes are defined in a router. For our work, we are are going to define our route in the router named `rental`. There are several approaches we can use when defining a router, which depends on how much reuse we want across a routes paths. The first approach is we can define all routes in a single router with nested definitions. For example:

```javascript
module.exports = {
  '/a': {
    '/b': {
      // add actions here
    }
  }
}
```

This approach works well if you are not modularizing your router definition such that a single router focuses on a single aspect of the application. Instead, you have a single monolithic router that defines every route in your application.&#x20;

As you scale your application to contain routes for many facets of the application, you will find this approach becomes hard to maintain. Moreover, it will be hard to [mount a router](/developer-guide/routers-and-controllers/routers#mounting-external-routers) defined inside a [Blueprint module](/developer-guide/untitled-1) since the mounted router may define more routes than you want to expose publicly from your Blueprint application.

The second approach is to modularize your routes across different routers. This approach, however, makes it hard to reuse parts of the routes path across different router definitions. To address this problem, you can place different routers that share common base paths in the same subdirectory structure. The names of the subdirectories will constitute the base paths for the routes defined in each router.

Since we want to plan for growth, and showcase how routers in subdirectories work, we will opt for the second approach of defining routers inside of subdirectories.

As mentioned before, the `super-rentals` example has a single route `GET /api/rentals`. Let's assume that if we want to define other routes, they will have the base path `/api`. We therefore want to define our routers in the subdirectory named `api`. Let's start with the single router named `rental`.

{% code title="app/routers/api/rental.js" %}

```javascript
const {Router} = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    '/rentals': {
    
    }
  }
});
```

{% endcode %}

As you will notice about, we define a router with the single path `/rentals`.  We do not include `/api` in the path definition because this router is located in the `api` subdirectory. This means that  routes defined in routers located in the `api` subdirectory will be prefixed with `/api`. If we placed this same router in the subdirectory named `v1`, which is a subdirectory of `api`, then the base path will be `/api/v1`.

{% hint style="info" %}
Defining routers in subdirectories is the recommended approach to versioning routes in your Blueprint application.
{% endhint %}

## Binding Your Route to an Action

We have defined the route for the application, but we need the route to perform an action when the client makes a request to `/api/rentals`. As previously discussed, the HTTP verb we need to respond to is the `GET` verb. We already have implemented the action that returns a list of rentals. Let's bind this path to that specific action.

Update the /rental path in the router specification with the code below.

{% code title="app/routers/api/rental.js" %}

```javascript
const { Router } = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    '/rentals': {
      // This statement will bind this route to the get action in the 
      // rental controller. Now, GET /api/rentals can handle client requests.
      get: {action: 'rental@get'}
    }
  }
});
```

{% endcode %}

Now, you should be able to go to the url <http://localhost:5000/api/rentals>� in your favorite browser, and it will display the list of rentals we defined in the [rental.get action](/quick-start/my-first-application/controllers#implementing-the-action).

## Integrating with EmberJS

Since we are basing this tutorial on the [super-rental tutorial in EmberJS](https://guides.emberjs.com/release/tutorial/ember-cli/), it is only fitting that we show you how to integrate the Blueprint application with the EmberJS `super-rental` application. There is minimal work needed to replace mirage with this Blueprint application. The main approach is to leverage the power of [adapters](https://guides.emberjs.com/release/models/customizing-adapters/) and [serializers](https://guides.emberjs.com/release/models/customizing-serializers/) in [ember-data](https://guides.emberjs.com/release/tutorial/ember-data/), which allows an EmberJS application to integrate with virtually any backend api service, including Blueprint.

Getting started, we made our life easy by returning data from our route in the [JSON-API specification](http://jsonapi.org/) because the `super-rental` application has configured [ember-data](https://guides.emberjs.com/release/tutorial/ember-data/) to handle JSON-API by default. We just have to instruct the application to retrieve the data from the Blueprint application instead of from mirage. We do this by implementing an application adapter that defines where the data is located.

{% code title="app/adapters/application.js" %}

```javascript
import DS from 'ember-data';

export default DS.JSONAPIAdapter.extend ({
  host: 'http://localhost:5000',
  namespace: 'api'
});
```

{% endcode %}

Voila!

There is nothing more that you need to write.

{% hint style="info" %}
You may have to [disable mirage in your EmberJS application configuration](http://www.ember-cli-mirage.com/docs/v0.1.x/server-configuration/#environment-options) if you do not see the Blueprint application handling requests from the EmberJS application.
{% endhint %}

Now, when you use the EmberJS application, you should notice the Blueprint application handling request from the client.

�

�


# Services

A service in Blueprint is a software component that operate in the background of the application, and outside of the [controllers](/developer-guide/routers-and-controllers/controllers), [routers](/developer-guide/routers-and-controllers/routers), and [listeners](/developer-guide/untitled). Services can also be references by other software components, including services themselves. For example, you could recreate a service that performs periodic background tasks, or a service that manages connections to a database.

In our example, we want to migrate the data stored in the [rental controller](/quick-start/my-first-application/controllers#implementing-the-action) to a service. This will allow different software entities in the Blueprint application, such as another controller, to reference the same data as the [rental controller](/quick-start/my-first-application/controllers#generating-your-controller).

## Defining the Service

First, lets generate the service using the Blueprint cli.

```bash
blueprint generate service rentals
```

This command will generate an empty service.

{% code title="app/services/rentals.js" %}

```javascript
const { Service, computed } = require ('@onehilltech/blueprint');

/**
 * @class rentals
 */
module.exports = Service.extend ({

});
```

{% endcode %}

The service is automatically loaded by the Blueprint application when started.&#x20;

## Implementing the Service

For the service, we need a method for adding rentals, deleting rentals, getting all the rentals, and getting a single rental. We are also going to initialize the service with the original data.

{% code title="app/services/rentals.js" %}

```javascript
const { Service, computed } = require ('@onehilltech/blueprint');

/**
 * @class rentals
 */
module.exports = Service.extend ({
  _rentals: null,

  rentals: computed ({
    get () { return this._rentals; }
  }),

  init () {
    this._super.call (this, ...arguments);

    this._rentals = [
      {
        type: 'rentals',
        id: 'grand-old-mansion',
        attributes: {
          title: 'Grand Old Mansion',
          owner: 'Veruca Salt',
          city: 'San Francisco',
          category: 'Estate',
          bedrooms: 15,
          image: 'https://upload.wikimedia.org/wikipedia/commons/c/cb/Crane_estate_(5).jpg'
        }
      },
      {
        type: 'rentals',
        id: 'urban-living',
        attributes: {
          title: 'Urban Living',
          owner: 'Mike Teavee',
          city: 'Seattle',
          category: 'Condo',
          bedrooms: 1,
          image: 'https://upload.wikimedia.org/wikipedia/commons/0/0e/Alfonso_13_Highrise_Tegucigalpa.jpg'
        }
      },
      {
        type: 'rentals',
        id: 'downtown-charm',
        attributes: {
          title: 'Downtown Charm',
          owner: 'Violet Beauregarde',
          city: 'Portland',
          category: 'Apartment',
          bedrooms: 3,
          image: 'https://upload.wikimedia.org/wikipedia/commons/f/f7/Wheeldon_Apartment_Building_-_Portland_Oregon.jpg'
        }
      }];
  },

  // get a single rental
  get (id) {
    return this._rentals.find (rental => rental.id === id);
  },

  // add a rental to the list.
  add (rental) {
    return this._rentals.push (rental);
  },

  // remove the rental from the list.
  remove (id) {
    let index = this._rentals.findIndex (rental => rental.id === id);

    if (index === -1)
      return false;

    this._rentals.splice (index, 1);
    return true;
  }
});
```

{% endcode %}

## Using the Service

Let's go back to our [`rental`](/quick-start/my-first-application/controllers#generating-your-controller) controller and re-implement the [`rental.get`](/quick-start/my-first-application/controllers#implementing-the-action) using the `rentals` service from above. To load a service into the [`rental`](/quick-start/my-first-application/controllers#generating-your-controller) controller, just use the [`service`](/developer-guide/services#accessing-a-service) computed property.

{% code title="app/controllers/rental.js" %}

```javascript
const {
  Controller,
  Action,
  service          // computed property for loading a service
} = require ('@onehilltech/blueprint');

/**
 * @class rental
 */
module.exports = Controller.extend ({
  // load the rentals service, name parameter is not needed
  rentals: service (),

  get () {
    return Action.extend ({
      execute (req, res) {
        // get the data from the rentals service
        const data = this.controller.rentals.rentals;
        res.status (200).json ({data});
      }
    })
  }
});
```

{% endcode %}

Let's break down the example above since we have made some changes to the original controller code. First, we load the service into the controller using the `service()` computed property function, which is available via the `rentals` property on the controller. Next, we updated the `get()` action implementation to retrieve the rental data from the service.

{% hint style="info" %}
All actions can access to the parent controller using the`this.controller` property.
{% endhint %}

Now, when you restart the application and open the browser to <http://localhost:5000/api/rentals>, you will get the same response as before. The only difference this time is the data is pulled from the `rentals` service, and not from local data in the controller.

�

�


# Resources & Resource Controllers

In the lesson about [creating a service](/quick-start/my-first-application/services), we created a service to manage the rentals. We then updated the [`rental.get`](/quick-start/my-first-application/controllers#implementing-the-action) method in the rental controller to return the list of rentals managed by the rental service. There were other methods in the rental service, such as `create()`, `get(id)`, and `remove(id)`, that we did not use. So, let's update our application to provide routes that call use these methods.

## Implementing a Resource Controller

### Declaring a Resource Controller

A resource controller is a specialized controller that supports CRUD operations (*i.e.*, create, retrieve, update, and delete). Blueprint provides a base implementation of a resource controller, which you can extend in your application as needed. Since we have a service that supports CRUD operations, let's update the `rental` controller become a resource controller.

First, update the rental controller by changing `Controller` to `ResourceController`, and define the name property on the controller as `rental`.

{% code title="app/controllers/rental.js" %}

```javascript
const {
  ResourceController,
  Action,
  service
} = require ('@onehilltech/blueprint');

/**
 * @class rental
 */
module.exports = ResourceController.extend ({
  name: 'rental',
  
  rentals: service (),

  get () {
    return Action.extend ({
      execute (req, res) {
        const data = this.controller.rentals.rentals;
        res.status (200).json ({ data });
      }
    })
  }
});
```

{% endcode %}

What we did was extended the `ResourceController` instead of the `Controller`. This gives our controller the ability to selectively extend the actions defined in the `ResourceController` class. The `get()` method is one of the methods defined on the `ResourceController`, so we do not have do anything.

{% hint style="info" %}
The `ResourceController` extends the `Controller`, which is why the`ResourceController` is still considered a Controller.
{% endhint %}

We also defined the `name` property. This is a required property because the router uses this name when it is auto-generating the routes for the corresponding resource, as shown in the table below with their corresponding method on the `ResourceController`.

| **Method** | **Verb** | **Path**   | **Description**             |
| ---------- | -------- | ---------- | --------------------------- |
| `create()` | `POST`   | `/`        | Create a new resource       |
| `getAll()` | `GET`    | `/`        | Query the resources         |
| `getOne()` | `GET`    | `/:nameId` | Get a single resource       |
| `update()` | `PUT`    | `/:nameId` | Update an existing resource |
| `delete()` | `DELETE` | `/:nameId` | Delete an existing resource |

### Implementing Its Actions

When implementing the actions on of a resource controller, you only need to override methods that correspond to operations that you want to support. In our super-rental API server, we only want to support the following CRUD operations:

* `create`
* `getOne`
* `getAll`
* `delete`

{% hint style="info" %}
The `ResourceController` methods that are not overridden return a `404 Not Found` HTTP response to the client.
{% endhint %}

Let's first implement the `getOne()` and `getAll()`. The getOne() method is define an action that returns a single resource and the getAll() method is define an action that returns resources that match the query. If there is no query, then we should return all the resources. Below is the implementation of `getOne()` and `getAll()`.

{% code title="app/controllers/rental.js" %}

```javascript
const {
  ResourceController,
  Action,
  service
} = require ('@onehilltech/blueprint');

/**
 * @class rental
 */
module.exports = ResourceController.extend ({
  name: 'rental',

  rentals: service (),

  // query all the resources
  getAll () {
    return Action.extend ({
      execute (req, res) {
        const data = this.controller.rentals.rentals;
        res.status (200).json ({ data });
      }
    })
  },

  // get a single resources, or return 404 Not Found.
  getOne () {
    return Action.extend ({
      execute (req, res) {
        const { rentalId } = req.params;
        const rental = this.controller.rentals.get (rentalId);

        if (rental) {
          res.status (200).json ({ data: [rental] });
        }
        else {
          res.sendStatus (404);
        }
      }
    })
  }
});
```

{% endcode %}

�As shown in the code above, we implement `getAll()` by changing the method name from `get()` to `getAll()`. Later, we will discuss how to update the `getAll()` action to support queries. The `getOne()` method is similar to the `getAll()` method. The main difference is we extract the resource id from the `req.params.rentalId` property on the request object. This is because the resource name is used to construct the dynamic path for the resource (*e.g.*, `GET /:rentalId`).

{% hint style="info" %}
The `req` and `res` object are [Express](http://expressjs.com/) [request](http://expressjs.com/en/4x/api.html#req) and [response](http://expressjs.com/en/4x/api.html#res) objects, respectively.
{% endhint %}

Now, the route <http://localhost:5000/api/rentals> will still return the list of rentals. And, you can access the data for each rental via their own url.

* <http://localhost:5000/api/rentals/grand-old-mansion>
* <http://localhost:5000/api/rentals/urban-living>
* <http://localhost:5000/api/rentals/downtown-charm>

We can implement the `delete()` method in a similar manner as the `getOne()` method. For example, we get the resource id from `req.params.rentalId`. We then pass this value to the `remove()` method on the `rentals` service. Here is the rental controller with the `delete()` method implemented.

{% code title="app/controllers/rental.js" %}

```javascript
module.exports = ResourceController.extend ({
  /// ....
  
  delete () {
    return Action.extend ({
      execute (req, res) {
        const { rentalId } = req.params;
        const result = this.controller.rentals.remove (rentalId);

        res.status (200).json (result);
      }
    });
  }
});
```

{% endcode %}

The last method we need to implement is the `create()` method. When a client makes a request to create a rental, it will do so using the `POST` HTTP verb. The data about the rental will be available on the `req.body` property. To implement the `create()` method, we need to get the rental data from `req.body`, and pass it to the `add()` method on the `rentals` service. Below is the implementation of the `create()` method.

{% code title="app/controllers/rental.js" %}

```javascript
module.exports = ResourceController.extend ({
  // ...
  
  create () {
    return Action.extend ({
      execute (req, res) {
        const { rental } = req.body;
        this.controller.rentals.add (rental);
  
        res.status (200).json ({data: [rental]});
      }
    })
  }
});
```

{% endcode %}

## Declaring Resources in Router

We have defined the controller actions for managing the rental resources. We now need to declare the routes that invoke each action we implemented above. One approach is to define each route the same way we did when we defined the original route for getting the rentals. For example, we could update the rental router with the following specification.

{% code title="app/routers/rental.js" %}

```javascript
const { Router } = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    '/rentals': {
      post: { action: 'rental@create' },
      get: { action: 'rental@getAll' },

      '/:rentalId': {
        get: { action: 'rental@getOne' },
        delete: { action: 'rental@delete' },
      }
    }
  }
});
```

{% endcode %}

This approach works, but we end up writing the same code each time we need to declare the routes for  a resource. Instead, let's use the `resource` property that is available when defining a route. The following code is equivalent to the code above.�

{% code title="app/routers/rental.js" %}

```javascript
const { Router } = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    '/rentals': {
      resource: { controller: 'rental' }
    }
  }
});
```

{% endcode %}

The `resource` property will auto-generate the routes for a resource using the name defined by the associated resource controller. In this case, the name defined in by the rental resource controller is `rental`.&#x20;

By default, the resource property will generate routes that bind with each action supported by the resource controller. For our example, however, we only support a subset of the actions (*i.e.*, create, get, and delete). We can therefore use the `allow` property to specify the routes the resource controller supports, or `deny` to specify the routes the resource controller does not support. In our example, we are going to use the `allow` property to specify the support routes on the resource controller. Below is the updated example.&#x20;

{% code title="app/routers/rental.js" %}

```javascript
const { Router } = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    '/rentals': {
      resource: { 
        controller: 'rental',
        allow: ['create', 'getOne', 'getAll', 'delete'] 
      }
    }
  }
});
```

{% endcode %}

When the client tries to update a rental resource, the Blueprint application will respond with `404 Not Found`.

�

�


# Validating & Sanitizing Input

One of the most important lesson you learn with implementing API service is that you never trust the input your receive. You must *validate the input*, which means check that the input passes constraints, and *sanitize the input*, which means converting it from a text-based value to its concrete representation, such as a `Date` or a `String`.

Blueprint facilitates validating and sanitizing the input on the controller action. The controller action has the option of using the `schema` property to perform static validation. The value of the `schema` property is a [schema definition from express-validator](https://express-validator.github.io/docs/schema-validation.html). You can also use the `validate()` method, which is used to perform dynamic and asynchronous validation.

In our `super-rentals` example, we only need to validate the id parameter for `getOne()`, `update()`, and `delete()`. The schema for each method will be the same so we are only going to show the schema for the `getOne()` method.&#x20;

{% code title="app/controllers/rental.js" %}

```javascript
module.exports = ResourceController.extend ({
  // ...
  
  getOne () {
    return Action.extend ({
      // express-validator schema
      schema: {
        [this.id]: {
          in: 'params',
          optional: false,
        }
      },
  
      execute (req, res) {
        const { rentalId } = req.params;
        const rental = this.controller.rentals.get (rentalId);
  
        if (rental) {
          res.status (200).json ({ data: [rental] });
        }
        else {
          res.sendStatus (404);
        }
      }
    })
  }
});  
```

{% endcode %}

�


# Unit Testing Your Application

In the previous lessons, we learned how to use [Resources & Resource Controller](/quick-start/my-first-application/resources-and-resource-controllers) to simplify the controllers implementation. Now, we need to test our implementation so we can ensure it is handling requests correctly.

Blueprint uses [mocha](https://mochajs.org/) and [`superagent`](https://www.npmjs.com/package/superagent) to facilitate unit testing. The benefit to Blueprint approach is it allows you to run unit tests without needing a front-end, such as Postman, to exercise the Blueprint application. You can also use [`chai`](https://www.chaijs.com/) to implement the test oracle for each unit test.

Using our current example, here is a simple unit test to check the `GET /api/rentals`.

```javascript
// tests/unit-tests/app/routers/rental.js

const { request } = require ('@onehilltech/blueprint-testing');
const { expect } = require ('chai');

describe ('app | routers | rental', function () {
  context ('GET', function () {
    it ('should get all the rentals', async function () {
      // Send a mock request to the api, and wait for the response.
      const res = await request ()
        .post ('/api/rentals')
        .expect (200);
        
      // res.body has the text from the response. 
      // From here you can use chai to implement test oracle via assertions.
    });
  });
});
```


# Policies

It is not uncommon to restrict access to different routes based on who is making the request. For example, you many want to restrict access to a route based a request's origin, IP address, or if the request has the correct authorizations.

Blueprint realizes this need through its [policy framework](/developer-guide/policies).  In this part of the tutorial, we will explore how to create a simple policy, attach it to a route, and then write a unit test to test the policy.

### Defining a policy

Let's say we want to restrict access to `GET /api/rentals` to requests that only have the header `Secret-Key` and the value of the header is set to `ssshhh`. &#x20;

> This example is for demonstration purposes only. Please do not do anything this simple in a production environment when it comes to securing an API.

To do this, we are going to create a policy as shown below. As shown in the example, our policy is first placed in the `/app/policies` directory. We then organize our policy under the `/rental` directory since this policy pertains to the rental resource. Lastly, we place the policy in a file named  `getAll.js`. This help us remember the policy is for getting all rentals (more on this later).

{% code title="// app/policies/rental/getAll.js.js" %}

```javascript
const { Policy } = require ('@onehilltech/blueprint');

/**
 * This is a simple demonstration of a policy.
 */
module.exports = Policy.extend ({
   /// The failure code used when the policy fails.
   failureCode: 'invalid_secret',
   
   /// The human readable message that can be displayed on the 
   /// client-side when this policy fails.
   failureMessage: 'The request has an invalid secret.',
   
   /**
    * Run the policy.
    *
    * @param req     The Express request object.
    */
   runCheck (req) {
     // Check the Secret-Key request header, but do not use something like this in
     // a production environment.
     
     return req.get ('Secret-Key') === 'ssshhh';
   }
 }); 

```

{% endcode %}

Each policy must implement the `runCheck(req)` method because this is the main entry point the framework uses to execute a policy. If the policy succeeds, it must return `true`. If the policy fails, it can return either `false`, or a failure object. The failure object is a hash that contains a `failureCode` and `failureMessage` property. As you see in the example above, the policy can also define a default `failureCode` and `failureMessage` at the top-level of the policy. The default failure code and failure message are used when the policy returns `false`.

In the example above, we are checking the request header for the value of the `Secret-Key` header. If the value is `ssshhh`, the policy returns `true`. If the value is not `ssshhh`, then the policy returns `false`.

Policies that return true are allowed to continue its routing process either to the next policy, or to the controller action for the route. Policies that return false stop the request handling, and return `403` to the client. The body of the response will contain the corresponding `failureCode` and `failureMessage` associated with the failed policy.

### Attaching the policy to a route

Now that we have defined a policy, we need to attach (or bind) the policy to the correct route. We do this in the router specification.&#x20;

Let's assume that we go back to the router we defined before we started using resources. This router is illustrated below. The router has a `policy` property that is used to define the policy for a route or an action. As shown below, we have specified the policy created above on the `/rentals` route defined below.

```javascript
// app/routers/api/rental.js

const { Router } = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    '/rentals': {
      // This policy applies to all requests /api/rentals regardless of the
      // HTTP verb (or action) called.
      policy: 'rentals.getAll',
      
      get: {
        // If we add the policy here, then it only applies to GET /api/rentals.
        policy: 'rentals.getAll', 
        
        // This statement will bind this route to the get action in the 
        // rental controller. Now, GET /api/rentals can handle client requests.
        action: 'rental@getAll'
      }
    }
  }
});
```

### Policies for resources

The example above illustrated how to manually attach a policy to a route. This works when you manually bind routes to actions in a router specification. When we use resources, however, we have to use a different approach. Instead, the framework automatically attaches policies to resource routes.  This is done by searching for a policy that matches resource name + action.

If you recall, we defined the policy for our example in a file named `/app/policies/rental/getAll.js`. We did this in preparation for replacing the manually specification of a policy with the automatic specification of a policy when using a resource. If we revert our design above back to the [resource approach](/quick-start/my-first-application/resources-and-resource-controllers), then we do not have to manually specify the policies. Instead, the Blueprint framework will search for policies that match this resource for each inferred action of a resource, such as `getOne`, `getAll`, and `update`.

```javascript
// app/routers/api/rental.js

const { Router } = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    '/rentals': {
      resource: { controller: 'rental' }
    }
  }
});
```

For the example above, the framework will search for the following optional policies in `app/policies`:

<table><thead><tr><th width="185.80503862592582">Policy</th><th width="209.8007946651397">Location</th><th>Description</th></tr></thead><tbody><tr><td><code>rental.create</code></td><td><code>rental/create.js</code></td><td>Policy for creating a resource.</td></tr><tr><td><code>rental.getOne</code></td><td><code>rental/getOne.js</code></td><td>Policy for getting a single resource.</td></tr><tr><td><code>rental.getAll</code></td><td><code>rental/getAll.js</code></td><td>Policy for getting many, or querying, a resource.</td></tr><tr><td><code>rental.update</code></td><td><code>rental/update.js</code></td><td>Policy for updating a resource.</td></tr><tr><td><code>rental.delete</code></td><td><code>rental/delete.js</code></td><td>Policy for deleting a resource.</td></tr></tbody></table>

### Testing your policies

You unit test your policies the same way you unit test any route. The main difference is instead of expecting a `200` response, you are expecting a `403` response. You can also check the body of the response to make sure its returning the correct failure code and failure message. Below is an example of checking the policy we created above.

```javascript
// tests/unit-tests/app/routers/rental.js

const { request } = require ('@onehilltech/blueprint-testing');
const { expect } = require ('chai');

describe ('app | routers | rental', function () {
  context ('GET', function () {
    it ('should get all the rentals', async function () {
      // Send a mock request to the api, and wait for the response. This request
      // succeeds because it has the correct value for Secret-Key header.
      
      const res = await request ()
        .get ('/api/rentals')
        .set ('Secret-Key', 'ssshhh')
        .expect (200);
        
      // res.body has the text from the response. 
      // From here you can use chai to implement test oracle via assertions.
    });
    
    it ('should fail because it has invalid Secret-Key header', async function () {
      // This reqeust will fail. We are checking the response code, and
      // the text in the response.
      
      await request ()
        .get ('/api/rentals')
        .set ('Secret-Key', 'This will fail!')
        .expect (403, {
          errors: [{
            code: 'invalid_secret',
            detail: 'The request has an invalid secret.',
            status: '403'
          }]});
    });
  });
});
```


# Developer Guide

Reference guide for developers


# The Object Model

The foundation for all objects in Blueprint


# Introduction

Introduction to the object model

One of the main goals of Blueprint is to promote good software design through accepted Software Engineering concepts such as modularization, separation of concerns, software design patterns,  software design principles, and clean code. To support this goal, Blueprint uses its own [object model](https://github.com/onehilltech/base-object) that allows us to promote and use good software design practices without compromising the powerful features of JavaScript.&#x20;

Much of the inspiration for our [object model](https://github.com/onehilltech/base-object) is derived from our experience using [EmberJS](https://emberjs.com/) for front-end development. Similar to core objects in EmberJS, we support many of the same features. The reason for deviation is that we need something specific to our framework needs, which we can extend as needed. We also wanted it to support ES6 out-of-the-box.

{% hint style="info" %}
The [object model](https://github.com/onehilltech/base-object) library for Blueprint is a stand-alone project that you can integrate into your own project. The Blueprint-specific concepts are not part of the [object model](https://github.com/onehilltech/base-object).
{% endhint %}

If you are familiar with object-oriented programming, then you will find learning Blueprint's object model fairly easy. If you are not familiar with object-oriented programming, it should not be hard to pick up.

Happy Coding!


# Classes and Instances

General overview of defining classes and creating instances

## Defining a Class

The Blueprint object model is based on principles from object-oriented programming. This means that we use classes to define all abstract data types. All classes in Blueprint extend the `BaseObject` (or `BO` for short) class. Below, we define a `Person` class.

{% code title="person.js" %}

```javascript
const {BO} = require ('@onehilltech/blueprint');

const Person = BO.extend ({
  firstName: 'Barack',     // default first name for all persons
  lastName: 'Obama',       // default last name for all persons
  
  fullName () { 
    return `${this.firstName} ${this.lastName}`;
  },
  
  greet () {
   console.log ('Hello, World!');
  }
});

module.exports = Person;
```

{% endcode %}

As shown above, you define a class by calling the  `BO.extend` static method. The extend method takes the definition of the class as its main parameter. The class definition is just a plain JavaScript object (also known as a hash) consisting of data properties (*e.g.*, `firstName` and `lastName`) and methods (*i.e.*, `fullName` and `greet`).&#x20;

{% hint style="info" %}
The *execution context* of a method is the current object.
{% endhint %}

{% hint style="info" %}
Unlike ES6 class definitions, you are not required to defined data properties in the constructor
{% endhint %}

The return value from the `create()` method is a JavaScript class object.

## Creating an Instance

The easiest way to create an instance of a class (*i.e.*, instantiate a class) is to use the `new` operator.

```javascript
let person = new Person ();
```

Above we created a new instance of the `Person` class. Once you create an instance of the class, you can use it like an object from any object-oriented programming language.

```javascript
console.log (person.fullName ());    // "Barack Obama"

person.firstName = 'George';
person.lastName = 'Bush';
console.log (person.fullName ());    // "George Bush"
```

### Using the Create Method

The other approach for creating an instance is to use the static `create()` method on the class.

```javascript
let person = Person.create();
```

This method for creating an instance is most useful when you want to apply a [mixin](/developer-guide/the-object-model/mixins) to the created instance.

### Initializing the Instance

Data properties in the class definition can have no value (*i.e.*, `null`), a default value, or be `undefined` (*i.e.*, not appear in the definition). This, however, does not mean you cannot initialize data properties when you create the object. Similar to the hash provided to the `extend()` method when defining the class, you can pass a hash to the object being created.

```javascript
let p1 = new Person ({firstName: 'George', lastName: 'Bush'});
let p2 = Person.create ({firstName: 'Bill', lastName: 'Clinton'});
```

You can even initialize the instance with data properties and methods that are not defined on the class.&#x20;

```javascript
let person = new Person ({firstName: 'George', middleInitial: 'W', lastName: 'Bush'});
```

{% hint style="info" %}
The data property does not have to exist on the corresponding class when passing the hash to the created object. This means the data property will be unknown to the corresponding class, but known to the client that created the instance.
{% endhint %}

{% hint style="info" %}
The initialization hash can also contain methods.
{% endhint %}

#### Using the init method

There are situations where defining a data property in the definition hash is not acceptable because all instances of the class will use the same variable. This is the case with object-like types in JavaScript, *e.g.*, objects and arrays. For example, let's assume the `Person` class from above has a data property named `friends`, which is an array of names.

{% code title="person.js" %}

```javascript
const Person = BO.extend ({
  // ...
  friends: [],
});
```

{% endcode %}

When we create instances of `Person`, all instances of `Person` will share the same `friends` array. For example, `p1` and `p2` from the example above would share the same `friends` array. If this is not the intended behavior you want, then you need to initialize the `friends` data property in the `init()` method.

{% code title="student.js" %}

```javascript
const Student = BO.extend ({
  // ...
  
  friends: null,
  
  init () {
    this._super.call (this, ...arguments);
    this.friends = [];
  }
});
```

{% endcode %}

{% hint style="info" %}
Use the `init()` method to initialize object-like data properties if you do not want all instances to share the same data property instance.
{% endhint %}

{% hint style="info" %}
The `init()` method *must always* call `this._super.call (this, ...arguments)`. Otherwise, the object model will not initialize the instance properly.
{% endhint %}

Now,  each instance of the `Person` class will have its own `friends` array.&#x20;

## Extending a Class

You've had a preview of extending a class when you created the `Person`. When you create a class, it will have a static `extend` method. You use this method to extend the class—creating a new class definition. For example, we can create a `Student` class from the `Person` class.

{% code title="student.js" %}

```javascript
const Student = Person.extend ({
  classification: null,
});
```

{% endcode %}

{% hint style="info" %}
Extending a class is also called *subclassing* in object-oriented programming.
{% endhint %}

The `Student` class will inherit the property and methods of the `Person` class. Similarly, we can create a `Undergraduate` class by extending the `Student` class.

{% code title="undergraduate.js" %}

```javascript
const Undergraduate = Student.extend ({
  /// ...
});
```

{% endcode %}

### Overriding a Base Class Method

When you extend a class, you have the option of overriding the methods in the base class. This means you are redefining its behavior to the new one that you provide. For example, let's assume we want the `Student` class to override the `greet()` method in the `Person` class.

{% code title="student.js" %}

```javascript
const Student = Person.extend ({
  greet () {
    console.log ('YOLO!');
  }   
});
```

{% endcode %}

Now, when we invoke the `greet()` method from an instance of a `Student`, we will get a different console message.

```javascript
let person = new Person ();
person.greet ();     // "Hello, World!"

let student = new Student ();
student.greet ();    // "YOLO!"
```

{% hint style="info" %}
If you do not override a base class method, the extended class will use (or inherit) the behavior of the base class method.
{% endhint %}

### Calling the Base Class Method

Just because you override a base class method in the extended class does not mean you do not need the behavior of the base class method. Sometimes, you many need to base class method's behavior in addition to the behavior you can provide in the extended class. For example, what if we want to print  the `Person` greeting in addition to the greeting from the `Student` class. We can do this by calling the base class method.

{% code title="student.js" %}

```javascript
const Student = Person.extend ({
  greet () {
    this._super.call (this, ...arguments);
    console.log (' YOLO!');
  }  
});
```

{% endcode %}

{% hint style="info" %}
Use `this._super.call (this, ...arguments)` or `this._super.apply (this, arguments)` to call the base class method. The former is the preferred approach over the latter approach for [performance reasons](https://jsperf.com/call-apply-segu).
{% endhint %}

Now, the `greet()` method from the `Student` class will print the greeting from the `Person` class in addition to its greeting.

```javascript
let student = new Student ();
student.greet ();    // "Hello, World! YOLO!"
```

##


# Computed Properties

How to use computed properties in the object model

## Overview

Computed properties are properties derived from the value of one or more properties on the current instance. For example, the `fullName` property on the `Person` class is defined as a method. But, we could define it as a property based on the `firstName` and `lastName` property.&#x20;

Unlike methods, computed properties are accessed like any other data property defined on the class itself. Likewise, computed properties can optionally be iterated over.

## Types of Computed Properties

We support the following types of computed properties:

* [Read-Write Properties](/developer-guide/the-object-model/computed-properties#read-write-properties)
* [Read-only Properties](/developer-guide/the-object-model/computed-properties#read-only-properties)
* [Constant Properties](/developer-guide/the-object-model/computed-properties#constant-properties)

### Read-Write Properties

*Read-write properties* are defined using the `computed()` method, and passing it an initialization hash. The should have a getter method, and an optional setter method. Let's see how we can redefine our `Person` class using computed properties.

{% code title="person.js" %}

```javascript
const { BO, computed } = require ('@onehilltech/blueprint');

const Person = BO.extend ({
  fullName: computed ({
    set (value) {
      [this.firstName, this.lastName] = value.split (' ');    
    }
    
    get () {
      return `${this.firstName} ${this.lastName}`;
    }
});
```

{% endcode %}

{% hint style="info" %}
Use the `computed()` method to define computed property on the class definition.
{% endhint %}

&#x20;We can then just use the computed property like any other data property.

```javascript
let person = new Person ({firstName: 'Bill', lastName: 'Clinton'});
console.log (person.fullName);            // "Bill Clinton"

person.fullName = 'Ronald Reagan';
console.log (person.fullName);            // "Ronald Reagan"
```

### Read-Only Properties

*Read-only properties* are defined in a similar manner as read-write properties. The main difference read-only properties do not have a `set` method on its computed property definition.

```javascript
const { BO, computed } = require ('@onehilltech/blueprint');

const Person = BO.extend ({
  fullName: computed ({
    set (value) {
      [this.firstName, this.lastName] = value.split (' ');    
    }
});
```

Now, anytime we set the `fullName` property, it will not change.

```javascript
let person = new Person ({firstName: 'Bill', lastName: 'Clinton'});
console.log (person.fullName);            // "Bill Clinton"

person.fullName = 'Ronald Reagan';
console.log (person.fullName);            // "Bill Clinton"
```

### Constant Properties

*Constant properties* are computed properties that do not change. The behavior of a constant property is therefore similar to that of [read-only properties](/developer-guide/the-object-model/computed-properties#read-only-properties). The main difference is the constant properties are not computed at run-time. Instead, you must provide its value when you are defining the property.

Here is an example of defining a constant property named `MINIMUM_AGE` on the `Person` class.

{% code title="person.js" %}

```javascript
const { BO, computed } = require ('@onehilltech/blueprint');

const Person = BO.extend ({
  /// ...
  MINIMUM_AGE: computed.constant (21)
});
```

{% endcode %}

## Enumerable Computed Properties

When you enumerate the properties of an object, computed properties are not included in the enumeration. To enable enumeration of computed properties, add the `enumerable` property to the computed property descriptor.

```javascript
const { BO, computed } = require ('@onehilltech/blueprint');

const Person = BO.extend ({
  fullName: computed ({
    enumerable: true,      // the property can be enumerated
    get () { return `${this.firstName} ${this.lastName}`; }
    set (value) { [this.firstName, this.lastName] = value.split (' '); }
});
```

For [constant properties](/developer-guide/the-object-model/computed-properties#constant-properties), add the property descriptor after the constant value.

```javascript
const { BO, computed } = require ('@onehilltech/blueprint');

const Person = BO.extend ({
  /// ...
  MINIMUM_AGE: computed.constant (21, {enumerable: true})
});
```

Now, the computed properties will appear when the properties of the parent object are enumerated.

## Configurable Computed Properties

By default, computed properties are not configurable. This means that once a property is defined on a object, it cannot be redefined. For example, neither an extended class cannot change the property definition, nor an object instance during initialization time.&#x20;

To change this behavior, use the `configurable` property on the property descriptor.

```javascript
const { BO, computed } = require ('@onehilltech/blueprint');

const Person = BO.extend ({
  fullName: computed ({
    configurable: true,      // the property is configurable
    get () { return `${this.firstName} ${this.lastName}`; }
    set (value) { [this.firstName, this.lastName] = value.split (' '); }
});
```

For [constant properties](/developer-guide/the-object-model/computed-properties#constant-properties), add the `configurable` property to the property descriptor after the value.

```javascript
const { BO, computed } = require ('@onehilltech/blueprint');

const Person = BO.extend ({
  /// ...
  MINIMUM_AGE: computed.constant (21, {configurable: true})
});
```

Now, you can redefine the property in extended classes and during object initialization.


# Aggregated Properties

Discusses the purpose and use of aggregated properties

## Background

As you have learned in [Classes and Instances](/developer-guide/the-object-model/classes-and-instances), it is possible to both define a class, and then extend the class to create a new class. This is our implementation of inheritance from object-oriented programming. When you extend an existing class, however, the extended class overwrites the values of the base class. This happens for both data properties and methods.

When a method overwrites the method from its base class, you can use the `_super` method to pass execution to the base class. But, when a data property overwrites its corresponding data property on the base class, the data property on the base class is not easily accessible. What about when you do not want to overwrite the data property on the base class, but extend it—similar to how we extend class?

{% hint style="info" %}
By default, data properties from an extended class hide the data properties on its base class, making them hard to access.
{% endhint %}

This is where aggregated properties come into the picture. The purpose of an aggregated property is to combine the property of the base class with that of the extended class. This allows the data properties to be extended in a similar manner to how a class definition is extended.

## Supported Types

Our object model supports the following types of aggregated properties:

* [Concatenated Properties](/developer-guide/the-object-model/aggregated-properties#concatenated-properties)
* [Merged Properties](/developer-guide/the-object-model/aggregated-properties#merged-properties)

### Concatenated Properties

Concatenated properties apply to array data properties. You use the `concatProperties` property on the class definition to define the list of properties that should be concatenated instead of overwritten.

```javascript
const Person = BO.extend ({
  concatProperties: ['greetings'],  // Define the concatenated properties
  greetings: ['Hello']
});

const Student = Person.extend ({
  greetings: ['YOLO']
});

let person = new Person ();
console.log (person.greetings);     // ["Hello"]

let student = new Student ();
console.log (student.greetings);    // ["Hello", "YOLO"]
```

{% hint style="info" %}
The concatenated properties also apply when initializing a created object.
{% endhint %}

### Merged Properties

Merged properties apply to plain JavaScript object data properties. You use the `mergedProperties` property on the class definition to define the list of properties that should be merged instead of overwritten.

```javascript
const Person = BO.extend ({
  mergedProperties: ['capabilties'],      // Define the merged properties
  
  capabilties: {
    a: { a: 1, b: 3}
    b: { a: 6 }
  }
});

const Student = Person.extend ({
  capabilties: {
    a: { a: 3, c: 5}
    c: { a: 1 }
  }
});

let person = new Person ();
console.log (person.capabilities);       // {a: { a: 1, b: 3}, b: {a: 6} }

let student = new Student ();
console.log (student.capabilities);      // {a: { a: 3, b: 3, c: 5}, b: {a: 6}, c: { a: 1 }}
```

{% hint style="info" %}
The merged properties also apply when initializing a created object.
{% endhint %}


# Mixins

Learn how to create and apply mixins

## Overview

A mixin is an entity that captures reusable data properties and methods, but cannot be instantiated. The reason we have mixins is because the our object model uses single inheritance—meaning a class can only have one class as its base class. If we want multiple classes to share data properties and methods from multiple entity types, then it is not possible.

## Creating a Mixin

You create a mixin using the `Mixin.create()` method. The create method takes a definition hash that contains data properties and methods, which is similar to how you created a class.

{% code title="events.js" %}

```javascript
const {Mixin} = require ('@onehilltech/blueprint');

const Events = Mixin.create ({
  on (name, method) { 
    // ...
  },
  once (name, method) { 
    // ...
  }
  emit (name, ...args) { 
    // ...
  }
});
```

{% endcode %}

## Using a Mixin

Once we have created a mixin, you can use it in two ways. The first approach is [applying the mixin to the class definition](/developer-guide/the-object-model/mixins#applying-mixin-to-class-definition). When you apply a mixin to a class definition, all instances of the class will have the mixin as part of their definition. The second approach is to [apply the mixin to an instance](/developer-guide/the-object-model/mixins#applying-mixin-to-object-instance) when it is created. When we use this approach, only the created instance will have the mixin as part of its definition. It does not impact the other instances of the class.

### Applying Mixin to Class Definition

The `extend()` method takes optional list of mixins before the class definition.&#x20;

{% hint style="info" %}
The signature of the `extend()` method is`BO.extend ([Mixin1, Mixin2, Mixin3,] definition)`.
{% endhint %}

For example, let's assume we want to mix in the `Events` mixin with the `Person` class. We can do that by preceding the definition with the mixin.

```javascript
const { BO } = require ('@onehilltech/blueprint');
const Events = require ('./events');

const Person = BO.extend (Events, {
  // The person class definition
});
```

Now, anytime we create a `Person` class, it will have access to the methods and data properties defined in the `Events` mixin.

### Applying Mixin to Object Instance

Similar to the `extend()` method, the `create()` method takes optional list of mixins that before the class definition.&#x20;

{% hint style="info" %}
The signature of the `create()` method is`BO.create ([Mixin1, Mixin2, Mixin3,] definition)`
{% endhint %}

For example, let's assume we want to mix in the `Events` mixin with the `Person` class. We can do that by preceding the definition with the mixin.

```javascript
const { BO } = require ('@onehilltech/blueprint');
const Events = require ('./events');

let president = Person.create (Events, {
  firstName: 'Barack',
  lastName: 'Obama'
});
```

Now, only the `president` instance will have access to the methods and data properties defined in the `Events` mixin.


# Routers and Controllers

Public facing interfaces and backend logic


# Introduction

Brief discussion about the role of routers and controllers

**Routers** and **controllers** are considered the foundational building blocks of a Blueprint application. A controller is an application entity that provides the execution logic for different facets of the Blueprint application via actions. Each action in a controller is responsible for handling a request, which can include validating and sanitizing the request input, processing the request, and sending a response to the request.

> A controller is an application entity that provides the execution logic for different facets of the Blueprint application via actions.

Routers are the main access point to the Blueprint application. The router exposes the public facing interface (or application programming interface) via paths (or urls). For example, `/messages` is a path exposed by a router that clients can invoke.&#x20;

> Routers are the main access point to the Blueprint application.

Each path in a router is connected to a single action on a controller. We call this a *route*.


# Routers

Learn about routers and how to implement them

## Defining a Router

Routers are the main entry point to a Blueprint application. The router consists of paths (*i.e.*, relative urls) that clients uses to make request against the application. The paths are then bound to controller actions to create *routes*. Routers are essential application entities. All routers are defined in `app/routers`.&#x20;

You define a router by extending the `Router` class with a router specification, and exporting the extended class from its router module. Below is an example router named `message` with an empty specification.

{% code title="app/routers/message.js" %}

```javascript
const { Router } = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    // TODO router specification goes here
  }
});
```

{% endcode %}

## Router Paths

The paths of a router are the relative urls that provide an entry point to the application. If you think of an application as a building, then the paths represent the entryways for the building. Each entryway is in a different location and provides access to a different part of the building.

Paths are defined as keys on the `specification` property of the router, and begin with a forward slash (`/`). The example below updates our `message` router with the single path `/messages`.

{% code title="app/routers/message.js" %}

```javascript
const { Router } = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    '/messages': {
    
    }
  }
});
```

{% endcode %}

Now, we have an entryway into our application. We, however, do not know what action we need to perform when a clients wants to use this path.

## Reactions to Paths

If you are familiar with HTTP requests, each path in the request requires a [HTTP verb](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods), such as `GET`, `POST`, `PUT`,  and `DELETE`. The verb notifies the server (*i.e.*, the application in our case) of what action to execute when a client sends a request to the corresponding path. In our current specification, we have defined a path, but we have not defined what HTTP verb on the path is active, and what action the HTTP verb executes. We call this a *reaction*.

{% hint style="info" %}
A *reaction* is when you define the HTTP verb, and the action its causes.
{% endhint %}

Let's update our `message` router to support creating messages.

{% code title="app/routers/message.js" %}

```javascript
const { Router } = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    '/messages': {
      post: { action: 'message@create' }
    }
  }
});
```

{% endcode %}

Now, our message router has defined its first route `POST /messages`. When a client sends this HTTP request to the application, it will execute the `create` action on the message `controller`. We will visit how to implement this action later in the guide. For now, let's focus on the route definition in the `message` router.

As shown in the `message` router, the key for nested objects of a path is a HTTP verb. In this example, the HTTP verb is `post`.&#x20;

{% hint style="info" %}
A Blueprint router supports the HTTP verbs defined in the [jshttp](https://github.com/jshttp/methods) module.
{% endhint %}

### Actions

The value (or reaction) of the HTTP verb in the router definition can be a controller action. This is signified by the `action` property in the hash associated with the corresponding HTTP verb. In our example above, the controller action is `message@create`. This means that `POST /messages` is going to invoke the `create` action on the `message` controller.

There is no one-to-one mapping of paths to controller actions. For example, it is possible to have different paths from the same router, or a different router, bind to the same controller action. This reason for doing so is because either path may have different [policies](/developer-guide/policies) for invoking the action.

#### Binding to default actions

Some controller may have a single default action named `__invoke()`. When binding a path to the default action of a controller, you do not need to provide the action name. Instead, just specify the controller name in the `action` property. The following example illustrates binding the path to the default action for the `message` controller.

{% code title="app/routers/message.js" %}

```javascript
const 
{ Router } = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    '/messages': {
      post: { action: 'message' }    // bind to default action in message controller
    }
  }
});
```

{% endcode %}

### Static Views

A [view](/developer-guide/application-resources/static-views) is a document that captures a reusable representation of a response to a request that can be rendered on demand.  An example of a view is an HTML document. Similar to actions, you can specify that a path is bound to a static view. Just use the `view` property instead of the `action` property for the corresponding route.

{% code title="app/routers/message.js" %}

```javascript
const { Router } = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    '/messages': {
      get: { view: 'messages' }
    }
  }
});
```

{% endcode %}

Now, the `GET /messages` route will use the `messages` view to display the messages to the users.

## Dynamic Routes

Up until this point, we have been defining static routes. A *static route* is a route that has a path with no variable parts. A *dynamic route* therefore is a route that has variable parts. For example, `/messages` is a static route. But, `/messages/1` and `messages/2` are dynamic routes. This is because the part of the path after `/messages` is can change depending what context the client is hoping to access.

We define dynamic routes by including a parameter in the path. A parameter begins with a colon (`:`). For example, `:messageId` is a parameter.

Let's define a route for getting a single message:

```javascript
const { Router } = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    '/messages': {
      get: { view: 'message' }
      
      '/:messageId': {
         get { action: 'messages@getOne'}
      }   
    }
  }
});
```

In the example above, `/messages/:messageId` is dynamic route. Likewise, the `:messageId` parameter will be accessible on  `req.params` as `req.params.messageId`.

## Nested Routes

You may have noticed that when we defined the [dynamic route for getting a single message](/developer-guide/routers-and-controllers/routers#dynamic-routes), we created a route under `/messages`. This is call a *nested routed*. Nested routes is Blueprint's method for allowing you to extend an existing route with a child route, and reduce problems related to defining related routes. The dynamic route from above is the same as this one.

```javascript
const { Router } = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    '/messages': {
      get: { view: 'message' }
    },
    '/messages/:messageId': {
      get { action: 'messages@getOne'}
    }   
  }
});
```

The main difference between the definition above, and the following one:

```javascript
const { Router } = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    '/messages': {
      get: { view: 'message' }
      
      '/:messageId': {
         get { action: 'messages@getOne'}
      }   
    }
  }
});
```

is we are inheriting the `/messages` definition. This means that allow properties, such as [policies](/developer-guide/policies) and [Express middleware](/developer-guide/routers-and-controllers/routers#using-middleware), of the `/messages` route will also apply to the `/messages/:messageId` route.

### Using Directories

As your Blueprint application grows, you will find that defining all your routes in a single router will not scale to your needs. This will even be the case with nested routes in single router. To assist with this problem, Blueprint allows you to use directories to define nested routes.&#x20;

For example, let's assume you are working on v1 of your Blueprint application, and the application has 3 different routers. As part of your design, you want all routes to have a `/v1` prefix. The simple approach is to just nest all paths in a router under `/v1`. This suffices, but it also means you have to do the same for each routers. Likewise, changing the name of the prefix means you have to update each router definition.&#x20;

An easier, and better, solution would be to not nest all the paths in each router under `/v1`, but place all routers under the `v1/` directory. For example:

```bash
app/routers
  - v1/
    - message.js
    - comment.js
    - like.js
```

Now, all routes in the `message`, `comment`, and `like` router will be prefixed with `/v1`. For example, `/v1/messages` and `/v1/messages/:messageId` are valid routes.

{% hint style="info" %}
Using directories for nested routes is a easy way to implement versioned routes (*e.g.*, `/v1` vs `/v2`).
{% endhint %}

## Middleware

[Express middleware](https://expressjs.com/en/guide/using-middleware.html) are methods that provide domain-specific functionality to an Express application. For example, you have middleware the logs all the requests to a database, or middleware the authenticates access to a given route. Since Blueprint is a framework built atop [Express](https://expressjs.com/), it is possible to use Express middleware in a Blueprint application.&#x20;

{% hint style="info" %}
Blueprint has built-in middleware for logging, parsing requests, cookies, and validating request input because their load order is important.
{% endhint %}

You use the `use` keyword to add middleware to a route. For example, here we are adding the [CORS middleware](https://github.com/expressjs/cors) to our route.

```javascript
const { Router } = require ('@onehilltech/blueprint');
const cors = require ('cors');

module.exports = Router.extend ({
  specification: {
    '/': {
      use: cors ()        // apply CORS middleware to route
    },
    
    '/messages': {
      get: { view: 'message' }
      
      '/:messageId': {
         get { action: 'messages@getOne'}
      }   
    }
  }
});
```

The `use` property takes an Express middleware function with the signature `function (req, res, next)`, or an array of Express middleware functions.

## Mounting External Routers

One feature you will learn when working with [Blueprint modules](/developer-guide/untitled-1) is you can define routers inside a module for reuse across different applications. The benefit of this feature is the [Blueprint module](/developer-guide/untitled-1) can provide a public access point for how the module can be used by a client. Routers defined in a Blueprint module, however, are not loaded by default. We do this because we want to allow developers to control what routers (and paths) are exposed by the containing application.

This means that developers need a method for defining what routers (and paths) from a [Blueprint module](/developer-guide/untitled-1) are available via the application. We call this process *mounting*.&#x20;

To mount a router, you define the path and use the `mount()` method. Here is an example of mounting a router to the `/images` path.

```javascript
const blueprint = require ('@onehilltech/blueprint');

module.exports = {
  '/images': blueprint.mount ('blueprint-images-cdn:images')
}

```

The example above will mount the `images` router from the `blueprint-images-cdn` [Blueprint module](/developer-guide/untitled-1). If you do not provide a module name (*i.e.*, only use `images`), then the router is assumed to be part of the application.


# Controllers

Learn about controllers, actions, and predefined actions like uploads

## What is a Controller?

The controller defines the backend logic for the application. It also contains actions responsible for handling requests from the client.&#x20;

All controllers are located in `app/controllers`.

## Defining a Controller

You defined a controller by exporting a class that extends the `Controller` class, or any existing derivation of the `Controller` class. Here we have defined a controller that will act as the corresponding controller from the [message router](/developer-guide/routers-and-controllers/routers) from our previous examples.

```javascript
const { Controller } = require ('@onehilltech/blueprint');

module.exports = Controller.extend ({
    // TODO Add properties and actions here
});
```

Right now, the controller is empty. But, just like we learned with [the object model](/developer-guide/the-object-model), we just need to provide a hash to the `extend()` method to define the actions what actions the controller supports.

## Actions

Actions implement the business-logic of the controller. The action is responsible for validating and sanitizing the input, executing the request, and sending a response.&#x20;

### Creating an Action

Actions on a controller are methods that return an extended version of the `Action` class. The name of the method represents the name of the action. This is the name that the router binds with when defining its [reactions](/developer-guide/routers-and-controllers/routers#reactions-to-paths) for a given path.

In our [examples from learning about routers](/developer-guide/routers-and-controllers/routers), we implemented a router named message. We assumed the purpose of this router was to provide an interface for managing messages. In our example, we defined a couple of paths, and reactions using actions on a `message` controller. Let's complete this example by implementing the `message` controller.&#x20;

#### Action Definition

First, we are going to start by defining the action on the `message` controller for creating the message. This action is responsible for handling `POST /messages` requests as defined in the message router.

{% tabs %}
{% tab title="app/controllers/message.js" %}

```javascript
const { Controller, Action } = require ('@onehilltech/blueprint');

module.exports = Controller.extend ({
  create () {
    return Action.extend ({
      execute (req, res) {
        // TODO Add code here
      }
    })
  }
});
```

{% endtab %}

{% tab title="app/routers/message.js" %}

```javascript
const { Router } = require ('@onehilltech/blueprint');
​
module.exports = Router.extend ({ 
  specification: {    
    '/messages': {      
      post: { action: 'message@create' }    
    }  
  }
});
```

{% endtab %}
{% endtabs %}

All actions must implement the `execute(req, res)` method, which is responsible for handling the request. The `execute(req, res)` method must return `null`, `undefined`, or a `Promise`. The `req` parameter is an [HTTP request object](http://expressjs.com/en/4x/api.html#req), and the `res` parameter is a [HTTP response object](http://expressjs.com/en/4x/api.html#res).

Since the extend behavior of this action is the create a message, we know the properties of the message to create will appear in the body of the request. Let's update our controller store the created messages.

{% hint style="info" %}
Ideally, we would store the messages in a database. But, for illustrations purposes only we are going to store the messages locally in the controller.
{% endhint %}

{% code title="app/controllers/message.js" %}

```javascript
const { Controller, Action, BO } = require ('@onehilltech/blueprint');
const { pick } = require ('lodash');

const Message = BO.extend ({
  id: null              // message id
  from: null,           // who the message is from
  to: null,             // who the message is to
  date: null,           // date of the message
  subject: null,        // message subject
  content: null,        // content of the message
  
  init () {
    this._super.call (this, ...arguments);
    
    if (!this.date) this.date = new Date ();
  }
});

module.exports = Controller.extend ({
  messages: null,          //collection of messsages
 
  init () {
    this._super.call (this, ...arguments);
    this.messages = [];
  },
  
  create () {
    return Action.extend ({
      _nextId: 0,      // id of the next message
      
      execute (req, res) {
        let id = this._nextId ++;
        let data = Object.assign ({id}, pick (req.body.message, ['from','to','date','subject','content']));
        let msg = new Message (data);
        
        this.controller.messages.push (msg);
        
        res.status (200).json ({message: msg});
      }
    })
  }
});
```

{% endcode %}

There is a lot going on in the example above, so let's unpack it. First, we create a class named `Message` which is a Wrapper Facade for each message we create. We then add a `messages` property to our controller. This will be used to store the messages we create. If you remember the discussion about [object-like properties in the object model](/developer-guide/the-object-model/classes-and-instances#using-the-init-method), then you will remember that we cannot initialize an array property when we define it. Instead, we must initialize the property in the `init()` method. In this case, we initialize the `messages` property to an empty array.

Lastly, we updated the `create()` action to create the message, which is located in `req.body`. We are expecting the data for the message to be under the `message` envelope. To create the message, we first compute the id of the next message using `_nextId`. We then create a data object, and use this data object to create a `Message` object. Last, we push the message object unto the collection of messages, and return a response to the client.

### Validating and Sanitizing Input

In our example above, we are expecting the body to contain the data for the message to create. One important step we failed to do is validate the input. Fortunately, validating the a request's input is a simple process.&#x20;

With Blueprint actions, you can validate input either statically using a schema or dynamically using a validate method.&#x20;

{% hint style="info" %}
Use schema validation when you can define how to validate the input when defining the action. Use dynamic validation when the input itself determine how to validate other parts of the input.
{% endhint %}

We have update the example to use schema validation, and an empty method for dynamic validation. Since we are not really using dynamic validation, we can actually remove the `validate(req)` method.

{% code title="app/controllers/message.js" %}

```javascript
// ...

module.exports = Controller.extend ({
  messages: null,          //collection of messsages
 
  init () {
    this._super.call (this, ...arguments);
    this.messages = [];
  },
  
  create () {
    return Action.extend ({
      // ...
      
      schema: {
        'message.to': { in: 'body', isEmail: true },
        'message.from': { in: 'body', isEmail: true },
        'message.date': { in: 'body', isDate: true, optional: true },
        'message.content': { in: 'body', isLength: { min: 1 } }
      },
      
      validate (req) { },
      
      // ...
    })
  }
});
```

{% endcode %}

Blueprint supports [express-validator](https://github.com/express-validator/express-validator) out-of-the-box. For schema validation, Blueprint uses the [schema validation](https://github.com/express-validator/express-validator#schema-validation) feature in [express-validator](https://github.com/express-validator/express-validator). As shown in the example, each input we need to validate is added the the `schema` property. Now that we have enabled request input validation, the `execute(req, res)` method will only be called if validation succeeds. This means there is no need to add validation logic to the `execute(req, res)` method.

#### Custom Validators and Sanitizers

(Coming Soon)

### Actions for Dynamic Routes

In our router example, we defined a [dynamic route](/developer-guide/routers-and-controllers/routers#dynamic-routes) for getting a single message (*i.e.*, `GET /messages/:messageId`). This path for this route had a router parameter named `messageId`. The parameter in the path is available on the `req.params` object. To illustrate how we can use this parameter in our action, below is the implementation of the `getOne()` action on the `message` controller.

{% code title="app/controllers/message.js" %}

```javascript
// ...
module.exports = Controller.extend ({
  // ...
  
  getOne () {
    return Action.extend ({
      schema: {
        messageId: { in: 'params', isInt: {min: 0}, toInt: true}
      },
      
      execute (req, res) {
        const {messageId} = req.params;
        const found = this.controllers.messages.find (message => message.id === messageId);
        
        if (found)
          return res.status (200).json ({message: found});
        else
          return res.sendStatus (404);  
      }
    });
  }
});
```

{% endcode %}

As shown in the `getOne()` method above, the action for this method defines a schema to validate the expected parameter. The action then uses the `messageId` parameter to search for the message that has an id that matches. If the message is found, the message is returned as the response. Otherwise, the action returns a 404 response.

### The Default Action

A default action is the action implied on the controller. The default action can exist if there are other actions on the controller. The [default action is used by the router](/developer-guide/routers-and-controllers/routers#binding-to-default-actions) if an action is defined by its controller and no action.

You define the default action of the controller implementing an \_\_invoke() method on the corresponding controller. For example, the code below gives a default action for the message controller.

{% code title="app/controllers/message.js" %}

```javascript
const { Controller } = require ('@onehilltech/blueprint');

module.exports = Controller.extend ({
  __invoke () {
    return Action.extend ({
      execute (req, res) {
        // TODO Add implementation here
      }  
    })
  }
});
```

{% endcode %}

Now, when we just use the `message` controller with no action in the router, it will use the `__invoke()` definition.

### Predefined Actions

The return value of a controller action is an `Action` class. Because the return value is a class and not an object, we can port an action classes to different controller actions. We can also extend an action class to create a more domain-specific action.

There exists several scenarios where we can provide a predefined action class that implements the boilerplate code, and defers context-specific behavior to the extended class.

{% hint style="info" %}
Actions use the [Template Method pattern](https://en.wikipedia.org/wiki/Template_method_pattern) to define the skeleton of an algorithm, and defer the implementation of the steps to subclasses.
{% endhint %}

The Blueprint framework provide the following actions out-of-the-box:

#### Views

This is a collection of actions for generating [view](/developer-guide/application-resources/static-views) responses.

* [**`ViewAction`**](https://github.com/onehilltech/blueprint/blob/master/lib/view-action.js) Generates a view based on the content of the request it is processing.
* [**`SingleViewAction`**](https://github.com/onehilltech/blueprint/blob/master/lib/single-view-action.js) Specialization of the ViewAction class that only supports a single view. Subclasses and instances of this class must define the `template` property.�

#### Uploads

This is a collection of actions for handling uploads. The upload actions are a Wrapper Facade for the [multer](https://github.com/expressjs/multer) node module. All subclasses of any action class below must implement the `onUploadComplete(req, res)` method, which is notified when the upload is complete.

* [**`ArrayUploadAction`**](https://github.com/onehilltech/blueprint/blob/master/lib/array-upload-action.js) An action for uploading an array of files. The uploaded files will be accessible on `req.files`.
* [**`FieldsUploadAction`**](https://github.com/onehilltech/blueprint/blob/master/lib/fields-upload-action.js) An action for accepting a mix of files.
* [**`SingleFileUploadAction`**](https://github.com/onehilltech/blueprint/blob/master/lib/single-file-upload-action.js) An action for uploading a single file. The file is expected to be part of an multipart/form-data request.
* [**`TextOnlyUploadAction`**](https://github.com/onehilltech/blueprint/blob/master/lib/text-only-upload-action.js)  An action for uploading text only.
* [**`UploadAction`**](https://github.com/onehilltech/blueprint/blob/master/lib/upload-action.js) Base class for all upload actions. This class will initialize a new instance of [multer](https://github.com/expressjs/multer) and store it internally for subclasses to use.


# Resources

Well-defined artifacts that are accessible

## What is a Resource?

In simple terms, a resource is an artifact managed by the application that has a unique id. The resource is expected to support the following actions:

* create
* retrieve&#x20;
* update
* delete

These actions are also know as [CRUD operations](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete).

In Blueprint, we consider resources to be first-class entities because implementing resource-like behavior is quite common. For example, the message example we used to discuss both routers and controllers implemented the create and retrieve actions. We were just missing the update and delete action. One thing you will notice over time is that you will implement behavior similar to the message example each time you need to interact with a entity managed application. Blueprint therefore wants to minimize the amount of code you must reinvent—thereby improving productivity and reduce potential errors.

## Defining a Resource

You define a resource by first binding a resource to path in the router. Then, you implement the corresponding resource controller.

### Declaring a Resource Path

You declare a resource path using the `resource` keyword. As shown in the example below,  we are declaring the `/messages` path as a resource path. As part of the declaration, we specify what controller the resource path should use to create its complete routes.

{% code title="app/routers/message.js" %}

```javascript
const { Router } = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    '/messages': {
      resource: { controller: 'message' }
    }
  }
});
```

{% endcode %}

When you declare a resource path, it will automatically define the following routes relative to the resource path.

| **Method** | **Action** | **Path** | **Examples**           | **Description**                |
| ---------- | ---------- | -------- | ---------------------- | ------------------------------ |
| POST       | `create`   | `/`      | `/messages`            | Create a one or more resources |
| GET        | `getAll`   | `/`      | `/messages`            | Query the resources            |
| GET        | `getOne`   | `/:rcId` | `/messages/:messageId` | Get a single resource          |
| PUT        | `update`   | `/:rcId` | `/messages/:messageId` | Update an existing resources   |
| DELETE     | `delete`   | `/:rcId` | `/messages/:messageId` | Delete a single resource       |
| GET        | `count`    | `/count` | `/messages/count`      | Query the number of resources  |

By default, we do not automatically define a route for deleting all the resources.

#### Allowing and Denying Routes

You may want to restrict what routes are available to a resource. For example, you prohibit directly creating a resource because it is created someone where else in the application. Likewise, you may prohibit a resource from being able to be deleted.

When you define a resource path, you can use the `allow` or `deny` keyword to permit or prohibit actions on the resource, respectively. If you use the `allow` keyword, then all resource actions are prohibited except the ones listed. Likewise, if you use the `deny` keyword, then all resource actions are permitted except for the ones listed.

Here is an example that restrict what actions are permitted.

```javascript
const { Router } = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    '/messages': {
      resource: { 
        controller: 'message',
        allow: ['getOne', 'getAll']
      }
    }
  }
});
```

Likewise, here is another example illustrating what actions *are not* permitted.

```javascript
const { Router } = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    '/messages': {
      resource: { 
        controller: 'message',
        deny: ['create', 'delete', 'update']
      }
    }
  }
});
```

### Implementing the Resource Controller

You implementing the resource controller the same way you implement any other controller. But, instead of extending the `Controller` class, you extend the `ResourceController` class. The `ResourceController` class has a methods that correspond to each action listed in the table above. You just have to provide the corresponding implementation for each supported action.

## More Information

The `ResourceController` class has empty methods for each action by design. This is because the implementation of a resource controller depends heavily on where the data is persisted. For example, a in-memory resource controller will store its resources in memory. Whereas, a [MongoDB resource controller](https://github.com/onehilltech/blueprint-mongodb/) will persists is resources to a [MongoDB database](https://www.mongodb.com/). We therefore recommend that you leverage a domain-specific resource controller since it will provide a default implementation for each action while giving you the ability to customize it accordingly.


# Models

Understand the purpose of application models

## Introduction

Models represent the data managed by the Blueprint application. For example, we can have models that define messages, comments, and likes.&#x20;

In Blueprint, we do not provide a general-purpose modeling language to define your models. Instead, we rely of domain-specific frameworks and libraries to define a model. For example, if you want to use [MongoDB](https://www.mongodb.com/), then you can use [mongoose](http://mongoosejs.com/) as your modeling language. Likewise, if you are using SQL, you can use [sequelize](http://docs.sequelizejs.com/) as your modeling language.&#x20;

Typically, there are [Blueprint modules](/developer-guide/untitled-1#module-listings) that provide support for different storage strategies In such cases, the module will dictate what framework or library to use. For example, the [blueprint-mongodb](https://github.com/onehilltech/blueprint-mongodb) module uses [mongoose](http://mongoosejs.com/). This means that when you use [blueprint-mongodb](https://github.com/onehilltech/blueprint-mongodb), its corresponding models will be defined using a [mongoose Schema](http://mongoosejs.com/docs/guide.html).

{% hint style="info" %}
All models are located in the `app/models` directory.&#x20;
{% endhint %}

## Defining a Model

As mentioned in the introduction, Blueprint does not provide a general-purpose modeling language for users to define models. Instead, Blueprint relies on existing frameworks and libraries to define models. This makes it easier for Blueprint to support polyglot data solutions.

To illustrate how to define a model, let's convert our [the message class we defined in the message controller](/developer-guide/routers-and-controllers/controllers#action-definition) to a local in-memory model. First, we create the `message` model.

{% code title="app/models/message.js" %}

```javascript
const { BO } = require ('@onehilltech/blueprint');

module.exports = BO.extend ({
  id: null              // message id
  from: null,           // who the message is from
  to: null,             // who the message is to
  date: null,           // date of the message
  subject: null,        // message subject
  content: null,        // content of the message
  
  init () {
    this._super.call (this, ...arguments);
    
    if (!this.date) this.date = new Date ();
  }
});
```

{% endcode %}

As you can see from the example above, we just move the class definition from the controller to its own module located in the `app/models` directory.

## Accessing a Model

After you define your models, you access a model by defining a data property with the value `model([name])`. The name parameter is the name of the model. If the name of the data property is the same as the model, then the name is not required.&#x20;

Let's update the `message` controller to use the `message` model.

{% code title="app/controllers/message.js" %}

```javascript
const { Controller, Action, model } = require ('@onehilltech/blueprint');
const { pick } = require ('lodash');

module.exports = Controller.extend ({
  messages: null,                // collection of messsages
  Message: model ('message'),    // load the message model
  
  init () {
    this._super.call (this, ...arguments);
    this.messages = [];
  },
  
  create () {
    return Action.extend ({
      _nextId: 0,      // id of the next message
      
      execute (req, res) {
        let id = this._nextId ++;
        let data = Object.assign ({id}, pick (req.body.message, ['from','to','date','subject','content']));
        let msg = this.controller.Message.create (data);
        
        this.controller.messages.push (msg);
        
        res.status (200).json ({message: msg});
      }
    })
  }
});
```

{% endcode %}

As shown in the example above, the `Message` data property is bound to the `message` model. We have to  give to specify the `name` parameter because the name of the data property is different from the name of the model. Then, in the `create()` action, we use the `Message` model to create a new message.

## Moving Forward

Again, this is just one example of create a model that uses a local in-memory model. The method you use for defining a model will vary depending on the storage strategy for you data. It is therefore for you to understand how you are storing you data, and identifying a library or framework to managed the data. Afterwards, accessing the model is the same regardless of what library or framework you use to manage the data.


# The Server

Learn how to configure the server

## Overview

The server is the part of the Blueprint application responsible for handling request. It is essentially a Wrapper Facade for an Express application. The server exists to provide functionality that is common across all Express application, such as listening on ports and [installing middleware in the correct order](/developer-guide/the-server#builtin-middleware). There are no extra steps need to use the server in your Blueprint application. You just need to configure it to meet you needs.

{% hint style="info" %}
You configure the server using the configuration file named `app/config/server.js`, or a corresponding configuration file for the node environment.
{% endhint %}

## Protocols

The server natively supports the `http` and `https` protocol.  You configure the protocols under the `protocols` section of the server configuration file.

### http

Here is an example configuration for `http` where we are setting the port number. The `http` hash is the options support for [`http.createServer`](https://nodejs.org/api/http.html#http_http_createserver_options_requestlistener).

{% code title="app/configs/server.js" %}

```javascript
module.exports = {
  protocols: {
    http: {
      port: 8080      // default is 80
    }
  }
}
```

{% endcode %}

### https

Here is an example configuration for `https` where we are setting the port number, public key, and private key. The `https` hash is the options support for [`https.createServer`](https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener).

{% code title="app/configs/server.js" %}

```javascript
module.exports = {
  protocols: {
    https: {
      port: 8443,      // default is 443
      key: blueprint.assetSync ('ssl/server.key'),
      cert: blueprint.assetSync ('ssl/serer.cert')
    }
  }
}
```

{% endcode %}

## Built-in Middleware

All built-in middleware is configured under the `middleware` property. If a specific middleware configuration is not defined and it does not have a default configuration, then it is not loaded. The server supports the following Blueprint middleware, in order.

### Morgan

[morgan](https://github.com/expressjs/morgan) is http request logging middleware for [Express](http://expressjs.com/).

#### Configuration

Use `middleware.morgan` property to configure [morgan](https://github.com/expressjs/morgan). If you do not provide a configuration for [morgan](https://github.com/expressjs/morgan), then a default one is provided. See the [morgan documentation for available options](https://github.com/expressjs/morgan#options).

{% code title="app/configs/server.js" %}

```javascript
module.exports = {
  middleware: {
    morgan: {
      // morgan options go here
    }
  }
```

{% endcode %}

### Body Parser

[bodyParser](https://github.com/expressjs/body-parser) is Node.js parsing middleware for [Express](http://expressjs.com/). It is responsible for parsing the body of a HTTP request and making the content available on `req.body`. [bodyParser](https://github.com/expressjs/body-parser) support different kinds of parsers, such as [JSON](https://github.com/expressjs/body-parser#bodyparserjsonoptions) and [url encoded](https://github.com/expressjs/body-parser#bodyparserurlencodedoptions).&#x20;

#### Configuration

Use `middleware.bodyParser` to define the configuration for [bodyParser](https://github.com/expressjs/body-parser). Each parser you want to support has a named configuration under `middleware.bodyParser`. [JSON](https://github.com/expressjs/body-parser#bodyparserjsonoptions) and [url encoded](https://github.com/expressjs/body-parser#bodyparserurlencodedoptions) body parsers are always enabled. You, however, can change the configuration of [JSON](https://github.com/expressjs/body-parser#bodyparserjsonoptions) and [url encoded](https://github.com/expressjs/body-parser#bodyparserurlencodedoptions) body parsers, and include others supported by the [bodyParser](https://github.com/expressjs/body-parser) middleware.

{% code title="app/config/server.js" %}

```javascript
module.exports = {
  middleware: {
    bodyParser: {
      json: {
        // add bodyParser.json options here
      },
      
      urlencoded: {
        // add bodyParser.urlencoded options here
      }
    }
  }
}
```

{% endcode %}

### Express Validator

[express-validator](https://github.com/express-validator/express-validator) is middleware for validating the input of an HTTP request. It is does this by adapting [validator](https://github.com/chriso/validator.js) into an [Express](http://expressjs.com/) middleware. [express-validator](https://github.com/express-validator/express-validator) is used by [actions](/developer-guide/routers-and-controllers/controllers#actions) to [validate and sanitize input](/developer-guide/routers-and-controllers/controllers#validating-and-sanitizing-input).

### Configuration

There is no configuration support for [express-validator](https://github.com/express-validator/express-validator).

### Cookie Parser (optional)

The [cookie-parser](https://github.com/expressjs/cookie-parser) middleware in responsible for parsing HTTP request cookies and making them available via `req.cookies`.

#### Configuration

Use the `middleware.cookies` property to configure the [cookie-parser](https://github.com/expressjs/cookie-parser) middleware. See the [cookie-parser](https://github.com/expressjs/cookie-parser) documentation for the [available configuration options](https://github.com/expressjs/cookie-parser#cookieparsersecret-options).

{% code title="app/configs/server.js" %}

```javascript
module.exports = {
  middleware {
    cookies: {
      secret: 'sshhh',    // secret for signing cookies
      options: { }        // [optional] an object that is passed to cookie.parse
    }  
  }
}
```

{% endcode %}

### Express Session (optional)

[express-session](https://github.com/expressjs/session) is very simple session middleware for Express. The session information is available on the `req.session` data property.

#### Configuration

Use the `middleware.session` property to configure the [express-session](https://github.com/expressjs/session) middleware. See the [express-session](https://github.com/expressjs/session) documentation for the [available configuration options](https://github.com/expressjs/session#options).

{% code title="app/configs/server.js" %}

```javascript
module.exports = {
  middleware: {
    session: {
      // Add configuration options here
    }
  }
};
```

{% endcode %}

### Passport (optional)

[Passport](http://www.passportjs.org/) is authentication middleware for [Node.js](https://nodejs.org/).&#x20;

#### Configuration

Use the `middleware.passport` data property to configure [Passport](http://www.passportjs.org/). If `middleware.passport.session` is defined in the server configuration file, then the server will [configure session support with the Passport middleware](http://www.passportjs.org/docs/configure/).&#x20;

{% code title="app/configs/server.js" %}

```javascript
module.exports = {
  middleware: {
    passport: {
      // optional Passport session configuration
      session: {
        // method for serializing a session to a response
        serializer () {
        
        },
        
        // method for deserializing a session from a request
        deserializer () {
        
        }
      }
    }
  }
}
```

{% endcode %}

### Custom (optional)

Custom middleware is middleware functions that should be applied the entire application that are not suited for inclusion via a router, and not built-in middleware supported by the server.

#### Configuration

Use the `middleware.custom` property to configure custom middleware. The `custom.middleware` property  takes either a [single Express middleware function](https://expressjs.com/en/guide/writing-middleware.html), or an array of [Express middleware functions](https://expressjs.com/en/guide/writing-middleware.html).

{% code title="app/configs/server.js" %}

```javascript
module.exports = {
  middleware: {
    custom: [ 
      // add middleware functions here
    ]
  }
}
```

{% endcode %}

## Static Files

Static files are assets on the server that are not dynamically generated. For example, an icon image file, a style sheet, or a javascript file could be considered a static file. The server is not considered with each individual static file, but where the static files reside.

#### Configuration

You use the static property in the server configuration file to define the location of the static files. The static property takes an array of paths to the static files. If the path is a relative path, then it is is relation the `app/` directory. If the path is an absolute path, then the specified path is used as-is.

{% code title="app/configs/server.js" %}

```javascript
module.exports = {
  statics: [
    '../public_html',
    '/var/files'
  ]
}
```

{% endcode %}


# Policy Framework

Learn how to authorize access to routes

## Introduction

Policies are application entities that authorize a request. A policy is called after a request is validated and sanitized and before the request is executed on the target action. When a policy fails, the default status code is 403. Examples of policies can include

* Verifying the value of the HTTP authorization header
* Checking for violations of rate limits
* Enacting a pay wall

All policies are located in `app/policies`.

## Implementing a Policy

You implement a policy by extending the `Policy` class, and implementing the `runCheck(req)` method. The `runCheck(req)` method must return `true` if the policy passes. If the policy fails, then the `runCheck(req)` method must return `false`, or an the object `{failureCode, failureMessage}`.

{% code title="app/policies/passthrough.js" %}

```javascript
const {Policy} = require ('@onehilltech/blueprint');

module.exports = Policy.extend ({
  runCheck (req) {
    return true;
  }
});
```

{% endcode %}

If the policy check has an asynchronous operation, such as querying a database, then the `runCheck(req)` method can return a `Promise`. The Promise can resolve with `true`, `false`, or the object `{failureCode, failureMessage}`.

## Default Failure Code and Message

The `failureCode` is an application-specific code used to identify the reason for failure. The `failureMessage` is a human readable message that can be displayed to the user. When apply fails, you have the option of returning the object `{failureCode, failureMessage}`. You also have the option of returning `false`. When you return false, there is specification of `failureCode` and `failureMessage`. This is where the default `failureCode` and `failureMessage` for the policy come into play.

{% hint style="info" %}
The default `failureCode` and `failureMessage` is used when the `runCheck(req)` method returns `false`.
{% endhint %}

The default `failureCode` and `failureMessage` are just properties on the `Policy`. Here we have updates the `passthrough` policy from above with a default `failureCode` and `failureMessage`.

{% code title="app/policies/passthrough.js" %}

```javascript
const {Policy} = require ('@onehilltech/blueprint');

module.exports = Policy.extend ({
  failureCode: 'passthrough_failed',
  failureMessage: 'The passthrough policy failed.',
  
  runCheck (req) {
    return true;
  }
});
```

{% endcode %}

Now, when the `runCheck(req)`  method returns false, it will send the following response:

```javascript
{
  errors: [
    {status: '403', code: 'passthrough_failed', detail: 'The passthrough policy failed.'}
  ]
}
```

## Setting Parameters

Policies can also take parameters, which can be used to configure dynamic behavior in a policy. For example, what if we want the passthrough policy to be configured with the result of `true` or `false`. This means we need a way to configure the policy with the expected result. We do this by via policy parameters.

To support parameters, implement the `setParameters()` method on the policy. Each argument in `setParameters()` is an individual parameter. Below, we have updated our simple passthrough policy to use a parameter to define the result of the policy.

{% code title="app/policies/passthrough.js" %}

```javascript
const {Policy} = require ('@onehilltech/blueprint');

module.exports = Policy.extend ({
  failureCode: 'passthrough_failed',
  failureMessage: 'The passthrough policy failed.',
  
  value: true,    // default value is true
  
  setParameters (value) {
    this.value = value;
  },
  
  runCheck (req) {
    return this.value;
  }
});
```

{% endcode %}

As illustrated above, the `setParameters(value)` method stores the parameter value. Likewise, the `runCheck(req)` method uses the parameter value as its result.

## Applying Policies to Routes

Now that we have defined our `passthrough` policy, our next step is to apply the policy to different routes. We apply a policy to a route by naming the policy using the `policy` property in the router specification.&#x20;

{% hint style="info" %}
Use dot notation to access policies located in subdirectories. For example, the policy `a/b/c` can accessed using the name `a.b.c`.
{% endhint %}

In this example, we are applying the passthrough polices to all routes under the `/messages` path.

{% code title="app/routers/message.js" %}

```javascript
const { Router } = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    '/messages': {
      policy: 'passthrough',
      post: { action: 'message@create' }
    }
  }
});
```

{% endcode %}

Now, anytime we the client sends a request to `/messages` on the application server, the passthrough policy will authorize the request.&#x20;

### Passing Parameters

The default behavior of the [`passthrough`](/developer-guide/policies#setting-parameters) policy is allow the authorization to succeed. This is because the default value of the `value` property is true. But, what if we want the authorization to fail. The [`passthrough`](/developer-guide/policies#setting-parameters) policy supports parameters, but we need to pass `false` to as a parameter value to the policy.

If you need to pass parameters to a policy, then you must use the `check(name, ...args)` method. The first parameter to the `check()` method is the name of the policy. The remaining arguments are the parameters to the policy in-order of their argument specification in `setParameters()`.

We have now updated the example so that the create route will experience a policy failure.

{% code title="app/routers/message.js" %}

```javascript
const { Router, policies: { check } } = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    '/messages': {
      policy: 'passthrough',
      post: { action: 'message@create', policy: check ('passthrough', false) }
    }
  }
});
```

{% endcode %}

## Optional Policies

An optional policy is a policy that is applied if it exists. This is useful when you are defining a router in a Blueprint module, and want to give the module user the option of applying a policy to a route. To declare a policy on a route optional, begin the name with a question mark (`?`). For example, the create action now has an optional policy.

{% code title="app/routers/message.js" %}

```javascript
const { Router, policies: { check } } = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    '/messages': {
      policy: 'passthrough',
      post: { action: 'message@create', policy: check ('?passthrough', false) }
    }
  }
});
```

{% endcode %}

## Negating Policies

Similar to optional policies, you can also negate a policy. For example, if the policy returns true, then the negated policy will return false. If the negated policy returns `false` or `{failureCode, failureMessage}`, then it will return `true`. To negate a policy, begin the policy name with a exclamation point (`!`). For example, the create action now has a negated policy.

{% code title="app/routers/message.js" %}

```javascript
const { Router, policies: { check } } = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    '/messages': {
      policy: 'passthrough',
      post: { action: 'message@create', policy: check ('!passthrough', false) }
    }
  }
});
```

{% endcode %}

## Aggregate Policies

An aggregate policy is a policy created by combining one or more policies. There are two common use cases supported by default. Either all the policies succeed or any of the policies succeed for the aggregate policy to succeed.

### all

Use the `all()` method to create an aggregate policy where all policies must succeed in order for the aggregate policy to succeed. The `all()` method takes a list of policies, and an optional `failureCode` and `failureMessage` parameter.

{% code title="app/routers/message.js" %}

```javascript
const { Router, policies: { check, all } } = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    '/messages': {
      policy: all ([
        'passthrough',
        check ('passthrough', true),
        all (['passthrough', check ('!passthrough', false)])
      ], 'passthroughs_failed', 'All passthrough policies failed')    
      post: { action: 'message@create', policy: check ('!passthrough', false) }
    }
  }
});
```

{% endcode %}

#### Ordered execution

Use `all.ordered()` to evaluate the aggregates policies in order instead of in parallel.

### any

Use the `any()` method to create an aggregate policy where at least one policies must succeed in order for the aggregate policy to succeed. The `any()` method takes a list of policies, and an optional `failureCode` and `failureMessage` parameter.

{% code title="app/routers/message.js" %}

```javascript
const { Router, policies: { check, all } } = require ('@onehilltech/blueprint');

module.exports = Router.extend ({
  specification: {
    '/messages': {
      policy: any ([
        'passthrough',
        check ('passthrough', true),
        any (['passthrough', check ('!passthrough', false)])
      ], 'passthroughs_failed', 'All passthrough policies failed')    
      post: { action: 'message@create', policy: check ('!passthrough', false) }
    }
  }
});
```

{% endcode %}

#### Ordered execution

Use `any.ordered()` to evaluate the aggregates policies in order instead of in parallel.


# Services

An overview of services and how to use them

## Introduction

Services are software entities that operate in the background of the application, and outside of the [controllers](/developer-guide/routers-and-controllers/controllers), [routers](/developer-guide/routers-and-controllers/routers), and [listeners](/developer-guide/untitled). Services are singletons as well—meaning only one instance of the service exists at all times.

Examples of services include:

* Connection manager for MongoDB
* Local caching algorithm for a content delivery network (CDN)
* Gateway for communicating with Firebase Cloud Messaging

All services are located in `app/services`.

## Implementing a Service

You implement a service by extending the `Service` class. Here is an example service for storing the [messages we originally stored in a controller](/developer-guide/routers-and-controllers/controllers#action-definition).

{% code title="app/services/messages.js" %}

```javascript

const { Service } = require ('@onehilltech/blueprint');

module.exports = Service.extend ({
  _messages: null,
  
  init () {
    this._super.call (this, ...arguments);
    this._messages = [];
  },
  
  push (msg) {
    this._messages.push (msg);
  },
  
  find (id) {
    return this._messages.find (msg => msg.id === id);
  }
});
```

{% endcode %}

As shown in the example implementation above, the service has methods for adding and finding messages.

## Accessing a Service

You access a service by defining a property with the value `service([name])`. This method will bind the service to the associated property.&#x20;

{% hint style="info" %}
The name parameter is require if the (file) name of the service does not match the name of the property. For example, if a service is in a file named `local-cache`, then you must use `service('local-cache')`to access the service.
{% endhint %}

Below, we have re-implemented the message controller to use the message service.

```javascript
const {Controller, model, service} = require ('@onehilltech/blueprint');

module.exports = Controller.extend ({
  messages: service (),       // access the messages service
  Message: model ('message'),
  
  create () {
    return Action.extend ({
      _nextId: 0,      // id of the next message
      
      // ...
      
      execute (req, res) {
        let id = this._nextId ++;
        let data = Object.assign ({id}, pick (req.body.message, ['from','to','date','subject','content']));
        let msg = this.Message.create (data);
        
        this.controller.messages.push (msg);
        
        res.status (200).json ({message: msg});
      }
    })
  },
  
  getOne () {
    return Action.extend ({
      // ...
      
      execute (req, res) {
        const {messageId} = req.params;
        const found = this.controllers.messages.find (messageId);
        
        if (found)
          return res.status (200).json ({message: found});
        else
          return res.sendStatus (404);  
      }
    });
  }
});
```

In the example above, you will notice that the `messages` property has been changed from an array to a reference to the `messages` service. Now, the controller will read and write message to and from the `messages` service. More importantly, other entities can access this service and manipulate to the same messages this controller is able to manipulate.

## Service Lifecycle

Services are loaded automatically by the application after the application has loaded its [configuration files](/developer-guide/managing-configurations). Once the service is loaded into member, its lifecycle methods are called in the following order:

1. **`configure`** This method is called when the service is to configure itself. The `configure()` method should not be confused with the `init()` method. The `init()` method is for synchronous configuration whereas the `configure()` method is for asynchronous configuration. This is because the configure method can return a `Promise` to signify asynchronous configuration.
2. **`start`** This method is called when the service is started. If the service must perform any asynchronous operations, then it can return a `Promise`.
3. **`destroy`** This method is called when the service is being destroyed. If the service must perform any asynchronous operations, then it can return a `Promise`.


# Messaging Framework

Publish and subscribe to events

## Overview

Blueprint has a built-in messaging framework that helps you to design a reactive application. The messaging framework is similar to [events in Node.js](https://nodejs.org/api/events.html), but events are handled asynchronously by default. This design approach allows controllers to fire off events without waiting for background tasks to complete—returning control as quick as possible to the client.

{% hint style="info" %}
The messaging framework consists of [messengers](https://github.com/onehilltech/blueprint/wiki/Application%3AMessaging#sending-messages-to-listeners) and [listeners](https://github.com/onehilltech/blueprint/wiki/Application%3AMessaging#defining-listeners-to-receive-messages).
{% endhint %}

## Object Events

The `BaseObject` class (see [The Object Model](/developer-guide/the-object-model)) has methods for emitting and consuming events specific to the corresponding object instance. To emit an event from the object, use the `emit(...args)` method. Use either the `once(name, ...args)` or `on(name, ...args)` method to consume the corresponding event a single time or any time it is emitted, respectively. Here is an example for emitting and consuming an event on an object.

```javascript
const { BO } = require ('@onehilltech/blueprint');

const Connection = BO.extend ({
  open (opts) {
    // do something..
    
    this.emit ('opened', this);
  }
});

// ...

let conn = new Connection ();
conn.on ('opened', conn => {
  console.log ('The connection is open');
});
```

As shown in the example above, the `Connection.open()` method emits the opened event on the object instance. We can then register to receive the event, which is illustrated with we call the `conn.on()` method. You can also use the `conn.once()` if you only want to listener to be notified once when a connection is opened, and not every time the connection is opened.

## Application Events

Application events are events emitted through the Blueprint application. This should not be confused with the actual application event types. Unlike the [object events discussed above](/developer-guide/untitled#object-events), the implementation logic for both application emitters and consumers is different.

### Implementing a Listener

All application event listeners are implemented in `app/listeners/[EVENT_NAME]` were `EVENT_NAME` is the name of the event you are listening. The application event listeners must also extend the `Listener` class in Blueprint. Here is an example of an application event listener responding to connection open events.

{% code title="app/listeners/conn.open/console.js" %}

```javascript
const { Listener } = require ('@onehilltech/blueprint');

module.exports = Listener.extend ({
  handleEvent (conn) {
    console.log ('The connection is open');
  }
});
```

{% endcode %}

The event listener must implement the `handleEvent()` method. Similar to the object events, the `handleEvent()` method takes a variable number of parameters. This count depends on the number of parameters passed to the `emit()` method.

### Emitting an Event

You emit an application event in a similar manner as emitting object events. The main different is you use `blueprint.emit()` method instead of directly emitting on the local object instance. Here is an example emitting the connection open event as an application event.

```javascript
const blueprint = require ('@onehilltech/blueprint'); 
const { BO } = blueprint;

const Connection = BO.extend ({
  open (opts) {
    // do something..
    
    this.emit ('opened', this);
    blueprint.emit ('conn.opened', this);
  }
});
```

As shown in this example, the first `emit()` method is publishing the event a local object instance. The second `emit()` is publishing the event on through the Blueprint application.

### The Application Instance

If you are implementing a Blueprint entity, such as a [controller](/developer-guide/routers-and-controllers/controllers), [listener](/developer-guide/untitled#implementing-a-listener), or [policy](/developer-guide/policies),  then you have access to the application instance as a data property. If you already have direct access to the application class, then you do not need to use `blueprint.emit()` and `blueprint.on()` or `blueprint.once()` to send and receive application events. Instead, you can use the `emit()`, `once()`, and `on()` method on the application instance.

### Predefined Events

The following events are predefined to the Blueprint application.

* `blueprint.app.init` - Called after the application is initialized.
* `blueprint.app.started` - Called after the application is started.

## Inter-Module Communication

One key feature of the messaging framework is entities can communicate with listeners in different [Blueprint modules](/developer-guide/untitled-1). We call this *inter-module communication*. This allows modules to be loosely coupled with other modules in an application. It also allows listening modules to react to module events without the source module knowing the listening module is dependent on its behavior.

## Synchronous Messaging

### Emitters

By default, emitting an event is an asynchronous operation. This means the client does not wait for all listeners to process the event before continuing. To make event processing a synchronous operation,  the client to wait for the event to be processed. You do this by waiting for the `Promise` returned from the `emit()` method to be resolved.

```javascript
conn.emit ('opened', this);                     // asynchronous

conn.emit ('opened', this).then (() => {        // synchronous

});
```

### Listeners

The listener also can be asynchronous. If the listener is performing background processing, then it can return a `Promise`. If the emitter is asynchronous, then it will not continue until the listener's promise is either resolved or rejected.

```javascript
const { Listener } = require ('@onehilltech/listener');

module.exports = Listener.extend ({
  handleEvent (conn) {
    return new Promise ((resolve, reject) => {
      // Add background processing code here
    });
  }
});
```


# Configuration Management

Learn how to define configurations

## Introduction

Configurations define property values used by the application to configure its behavior.

All configurations are located in `app/configs` directory. Environment-specific configurations (*e.g.*, NODE\_ENV=production) must reside in the `env` subdirectory and named after the target environment (*e.g.*, `app/configs/env/production`). Environment-specific configurations overwrite the values in general-purpose configuration files.

## Defining a Configuration

Define a configuration by exporting an object from the configuration file.

{% code title="app/configs/facebook.js" %}

```javascript
module.exports = {
  api_key: 'api key goes here'
};
```

{% endcode %}

## Accessing the Configuration

You access the configuration by looking it using the `blueprint.lookup()` method.  Because application configuration are the first resource loaded, it is safe to lookup a configuration at any time within in the servers lifetime. For example, the code snippet below shows how to access the Facebook API key from the configuration above:..

{% code title="app/controllers/facebook.js" %}

```javascript
const {Controller} = require ('@onhilltech/blueprint');

module.exports = Controller.extend ({
  apiKey: null,
  
  init () {
    this._super.call (this, ...arguments);
    const config = this.app.lookup ('config:facebook');
    this.apiKey = config.apiKey;
  }
});
```

{% endcode %}


# Application and Resources

Miscellaneous topics about the application


# Lookup Operation


# Views

## What is a View?

We briefly introduced you to views when we discussed [binding actions to static views](/developer-guide/routers-and-controllers/routers#static-views) in the router definition. Views are well-defined, reusable representation of a response to a request. Views can be static—meaning there are no variable definitions in the view, or dynamic—meaning there are variable portions in the view.

{% hint style="info" %}
All views are located in `app/views`.
{% endhint %}

## Supported View Types

Blueprint does not have its own, proprietary view type. Instead, Blueprint support any view type (*i.e.*, template engine) supported by [consolidate.js](https://github.com/tj/consolidate.js/). You just have to

1. Install the node module for the template engine you plan to use for your view type; and
2. The extension of the view must match the name of its corresponding template engine.

For example, if you want to use [pug](https://github.com/pugjs/pug) as the template engine for your views, then your views must have the file extension in `.pug`. Likewise, if you want to use [handlebars](https://handlebarsjs.com/), then your views must have the file extension `.handlebars`.

{% hint style="info" %}
Blueprint will automatically configure Express to support the different kinds of views located in `app/views`. There is no need to manually register the different template engines with Express.
{% endhint %}


# Assets

## What are Assets?

Assets are application resources that support the functionality of the application, but do not have a standardized role in the application. For example, the public and private key need to support SSL would be considered an asset.

{% hint style="info" %}
All assets are located in `app/assets`.
{% endhint %}

## Using Assets

Depending on your needs, there are a couple of ways to load an asset. The first is to load the asset asynchronously via the `asset()` method.

```javascript
const blueprint = require ('@onehilltech/blueprint');

function doSomething () {
  return blueprint.app.asset ('publicKey').then (publicKey => {
    // do something with the loaded asset
  });
}
```

The second approach is to load the asset synchronously.

```javascript
const blueprint = require ('@onehilltech/blueprint');

function doSomething () {
  const publicKey = blueprint.app.assetSync ('publicKey');
  
  // do something with the loaded asset
}
```

{% hint style="info" %}
Loading an asset synchronously is ideal when you must use the asset in a Blueprint configuration file.
{% endhint %}


# Blueprint Modules

Codify design solutions into reusable modules

## What is a Blueprint Module?

A **Blueprint module** is a node module that contains a reusable Blueprint entities that can be applied to a Blueprint application. The goal of a Blueprint module is to provide functionality that address a certain application concern. For example, a Blueprint module many provide support for MongoDB, or it may implement a solution for integrating a paywall into your application. This way, the Blueprint application developer does not have to implement the solution themselves.

## Creating a Blueprint Module

It is not hard to create a Blueprint module. First, you need to create a standard Blueprint application.

```bash
blueprint new [name]
```

After the Blueprint application is created, add `blueprint-module` to the `keywords` property in the generated `packaged.json` file. Now, save the application and publish it using `npm`.

You have now created your first Blueprint module.

## Loading Blueprint Modules

The Blueprint application automatically loads all Blueprint modules. It does so by using a postorder depth-first search of the dependencies defined in `package.json`, and loading all modules that have the keyword `blueprint-module`. This ensures that all dependencies are available to the parent module, or application, when it is loaded into memory.

{% hint style="info" %}
A Blueprint module can depend on other Blueprint modules.
{% endhint %}

When a Blueprint module is loaded into memory, the module is added to the Blueprint application and the entities in the Blueprint module are merged with the entities in the application. If an entity with the same type and name already appears in the application, it is overwritten. The overwritten entity, however, will still be accessible via the application. You just have to include the Blueprint module name when you are perform a [lookup operation](/developer-guide/application-resources/lookup-operation). For example

```javascript
blueprint.lookup ('module-a:model:message');    // using lookup() method
blueprint.model ('module-a:message');           // using model() method 
```

## Supported Entities

The following entities can be loaded from a Blueprint module into a Blueprint application:

* Controllers
* Listeners
* Models
* Policies
* Resources
* Routers
* Sanitizers
* Services
* Validators

{% hint style="info" %}
When a router is loaded from a Blueprint module, its routes *are not* automatically added to the Blueprint application. Instead, you must [mount a router](https://onehilltech.gitbook.io/blueprint/developer-guide/routers-and-controllers/routers#mounting-external-routers) for it to be useable from the Blueprint application.
{% endhint %}

## Module Directory

The following is a list of know Blueprint modules.

### Authentication

* [Gatekeeper](https://github.com/onehilltech/gatekeeper) - Token-based authentication

### Communication/Messaging

* [Greenlock](https://github.com/onehilltech/blueprint-greenlock) - Let's Encrypt support for free, automated SSLs
* [Firebase Messaging](https://github.com/onehilltech/blueprint-firebase-messaging) - Google Firebase Messaging support
* [Socket.IO](https://github.com/onehilltech/blueprint-socket.io) - Socket.IO support

### Data Models

* [MongoDB](https://github.com/onehilltech/blueprint-mongodb) - MongoDB support via Mongoose

### Documentation

* [Swagger UI](https://github.com/onehilltech/blueprint-swagger) - generate and view Swagger specification from application


# Blueprint Cluster

Run application in cluster mode


# What is a Blueprint Cluster?

Brief introduction to Blueprint clusters and their importance

[Clustering](https://nodejs.org/api/cluster.html) in NodeJS is the process of running multiple instances of a NodeJS application such that one process is the master process and the other processes are worker processes. This is necessary feature because a NodeJS application is single-threaded. This means that all events are processed by the same execution thread. We you run a NodeJS application on a multi-core machine, it is hard for the NodeJS application to take advantage of computing power available via the many cores on the machine.

We understand the importance of [running a NodeJS cluster](https://nodejs.org/api/cluster.html) when it relates to scaling an NodeJS application to handle large numbers of requests. We therefore have integrated cluster support into Blueprint.

{% hint style="info" %}
A *Blueprint cluster* is when you run a Blueprint application as a NodeJS cluster.
{% endhint %}

{% hint style="info" %}
Blueprint cluster is an experimental feature. Its functionality may change in the future as we learn more about its usage in the wild.
{% endhint %}


# Running a Blueprint Cluster

How to launch a Blueprint cluster

## Running a Standard Blueprint Cluster

It is not hard to run a Blueprint cluster. It's as simple as passing a command-line argument to the NodeJS application.

```bash
node ./app --cluster
```

The above command will launch a Blueprint cluster that has 1 master process and *N* worker processes where *N* is the number of cores available on the host machine. For example, if the host machine has 64 cores (or processing units), then it will launch 1 master process and 64 worker processes.

{% hint style="info" %}
Blueprint cluster uses `os.cpus()` to detect the number of cores on the host machine.
{% endhint %}

## Controlling the Number of Worker Processes

You can also pass a positive integer to the `--cluster` argument to limit the number of worker processes spawned by the master process.

```bash
node ./app --cluster=8
```

In the example above, the master process will spawn 8 worker processes. You can pass a positive integer that is greater than the number of cores available on the host machine. For example, a host machine can have 8 cores, but you pass the argument `--cluster=12`. In such cases, we will display a warning message. We do not restrict this behavior because you have more domain knowledge about your application and its behavior. We just do not recommend spawning more worker processes than cores available on the host machine to ensure the worker processes are not competing for processing time.


# Technical Details

## Worker Processes are Isolated

When you run a Blueprint cluster, each worker processes is isolated from its peers and from the parent process. This means that each worker process has its own copy of the Blueprint application. Moreover, it means that each worker process cannot directly access the state of its peers. It is important to note this fact because it is easy to misunderstand why two worker processes are experiencing unexpected behavior—especially if your Blueprint application is stateful.

## Communicating Between Master and Worker Process

It is possible to communicate between the master and worker processes. At the moment, Blueprint cluster does not have native abstractions for supporting such communication needs. If you need to communicate between the master and worker process, then you have to rely on the abstractions from the [native NodeJS cluster module](https://nodejs.org/api/cluster.html).


# Testing Framework

Learn to write test cases

## Overview

Testing is an integral part of any application. We therefore have a node module and guidelines to testing a Blueprint application. We use the following middleware to facilitate testing:

* [chai](http://www.chaijs.com/)
* [chai-datetime](https://github.com/mguterl/chai-datetime)
* [mocha](https://mochajs.org/)
* [superagent](https://github.com/visionmedia/superagent)
* [supertest](https://github.com/visionmedia/supertest)

The remainder of this section will detail how to write test for Blueprint.

## Installation

The testing module is automatically installed when you generate a new Blueprint project. But, in case you need to manually install it, or update to the latest version, use the following command.

```bash
npm install --save-dev @onehilltech/blueprint-testing 
```

{% hint style="info" %}
Do not forget to the `--save-dev` option when installing the `blueprint-testing` module.
{% endhint %}

## Running Test Cases

The simplest way to run your test cases is via `npm` on the command-line.

```bash
npm test
```

This will instruct `npm` to run all test cases in your `tests/unit-tests`.

### Using an IDE

npm is just one way to run your test cases, but you are not restricted to only using npm. You can use your favorite IDE to run your tests cases, such as [WebStorm](https://www.jetbrains.com/webstorm/). If you choose to run your test cases via an IDE, you must remember that `tests/unit-tests/bootstrap.js` must load first  before running any test cases. This file will load your Blueprint application into memory, and make the application resources available for testing. If you fail to load this file first during your testing exercises, you will get error messages related to the application not being loaded. A common solution to ensure `tests/unit-tests/bootstrap.js` loads first is to set `tests/unit-tests` as the starting directory for your unit tests.

## Testing Routes

You test different routes in Blueprint by sending requests to paths on the Blueprint application under test. For example, the [message router from our previous examples](/developer-guide/routers-and-controllers/routers#reactions-to-paths) defined the route `POST /messages`. We can test this route by sending a request a `POST` request to `/messages`.

{% code title="tests/unit-tests/app/routers/message-test.js" %}

```javascript
const { request } = require ('@onehilltech/blueprint-testing');

describe ('app | routers | message', function () {
  it ('should create a message', function () {
    const message = { 
      id: 0, 
      to: 'john.doe@me.com',
      from: 'jane.doe@you.com',
      date: Date.now (), 
      subject: 'Dummy Message',
      content; 'This is a dummy message.'
    };
    
    return request ()
      .post ('/messages')
      .send ({message})
      .expect (200, {message});
  });
});
```

{% endcode %}

As shown in the example above, we start by importing the `request` method from [blueprint-testing](https://github.com/onehilltech/blueprint-testing). The request method is a helper method that will return a [supertest request](https://github.com/visionmedia/supertest) object that initiates a http request against the Blueprint application. The request has the option of returning a `Promise` that can be returned from the unit testing method to signify asynchronous execution.

## Testing Blueprint Modules


# Command-line Interface (Coming Soon)


