# Routers & Routes

We have[ implemented a controller](https://blueprint.onehilltech.com/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](https://blueprint.onehilltech.com/developer-guide/routers-and-controllers/routers#mounting-external-routers) defined inside a [Blueprint module](https://blueprint.onehilltech.com/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](https://blueprint.onehilltech.com/quick-start/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.

�

�
