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
.
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.
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
.
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
Let's update our message
router to support creating messages.
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
.
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.
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.
Static Views
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:
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
The main difference between the definition above, and the following one:
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.
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.
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:
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.
Middleware
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
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.
Last updated