Skip to main content

Routing

This guide covers the user-facing features of Nodos routing.

After reading this guide, you will know:

  • [โœ“] How to interpret the code in config/routes.yml.

  • [โœ“] How to construct your own routes

The Purpose of the Nodos Router#

The users of your website or web application can visit different URL's like /, /about or /user/1. To make these URLs work, you will have to define them as routes.

Routers are the main hubs of Nodos applications. They match HTTP requests and dispatch them to a controller's action, and define a series of pipeline transformations scoped to a set of routes.

Routes are definedinside the config/routes.yml.

- app/     config/       routes.yml

Routes file#

The routes for your application or engine live in the file config/routes.yml and typically looks like this:

pipelines:  browser:    - '@nodosjs/view-extension/fetchFlash'    - '@nodosjs/view-extension/protectFromForgery'
scopes:  - name: /    pipeline: browser    root: true    routes:      - resources: users

Both the router and controller module names same.

The pipeline: browser line will get a full treatment in the Pipeline section of this guide.

For now, you only need to know that pipelines allow a set of plugs to be applied to different sets of routes.

Inside block, we have our first actual routes /users.

When your Nodos application receives an incoming request for: GET /users/1 it asks the router to match it to a controller action.

If the first matching route is: get '/users/:id' the request is dispatched to the users controller's index action with { id: '1' } in params.

Resource Routing on the Web: the Nodos Default#

Resource routing allows you to quickly declare all of the common routes for a given resourceful controller.

A single call to resources can declare all of the necessary routes for your index, show, new, edit, create, update, and destroy actions.

Browsers request pages from Nodos by making a request for a URL using a specific HTTP method, such as GET, POST, PATCH, PUT and DELETE.

Each method is a request to perform an operation on the resource. A resource route maps a number of related requests to actions in a single controller.

When your Nodos application receives an incoming request for:

DELETE /users/1

it asks the router to map it to a controller action. If the first matching route is:

    routes:      - resources: users

Nodos would dispatch that request to the destroy action on the users controller with { id: '1' } in params.

CRUD, Verbs, and Actions#

In Nodos, a resourceful route provides a mapping between HTTP verbs and URLs to controller actions.

By convention, each action also maps to a specific CRUD operation in a database.

A single entry in the routing file, such as:

    routes:      - resources: users

creates eight different routes in your application, all mapping to the Users controller.

Running npx nodos routes now shows that we have all the routes.

Name             Verb   URI Pattern                       Pipeline Controller#Actionusers            GET    /users                            browser  users#indexbuildUser        GET    /users/build                      browser  users#buildusers            POST   /users                            browser  users#createuser             GET    /users/:id                        browser  users#showeditUser         GET    /users/:id/edit                   browser  users#edituser             PATCH  /users/:id                        browser  users#updateuser             PUT    /users/:id                        browser  users#updateuser             DELETE /users/:id                        browser  users#destroy

Because the router uses the HTTP verb and URL to match inbound requests, four URLs map to eight different actions.

Nested Resources#

It is also possible to nest resources in a Nodos router.

Let's say we also have a posts resource which has a many-to-one relationship with comments. Let's add a new resource.

That is to say, we have many posts, and an individual comment belongs to only one post.

We can represent that by adding a nested route in config/router.yml like this:

pipelines:  browser:    - '@nodosjs/view-extension/fetchFlash'    - '@nodosjs/view-extension/protectFromForgery'
  api:    - example/setLocale    - example/setLocale
scopes:  - name: api    pipeline: api    routes:      - resources: users  - name: /    pipeline: browser    root: true    routes:      - resources: users      - resources:          name: posts          routes:            - resources: comments

When we run npx nodos routes now, in addition to the routes we saw for users above, we get the following set of routes:

Name             Verb   URI Pattern                       Pipeline Controller#Actionusers            GET    /users                            browser  users#indexbuildUser        GET    /users/build                      browser  users#buildusers            POST   /users                            browser  users#createuser             GET    /users/:id                        browser  users#showeditUser         GET    /users/:id/edit                   browser  users#edituser             PATCH  /users/:id                        browser  users#updateuser             PUT    /users/:id                        browser  users#updateuser             DELETE /users/:id                        browser  users#destroyposts            GET    /posts                            browser  posts#indexbuildPost        GET    /posts/build                      browser  posts#buildposts            POST   /posts                            browser  posts#createpost             GET    /posts/:id                        browser  posts#showeditPost         GET    /posts/:id/edit                   browser  posts#editpost             PATCH  /posts/:id                        browser  posts#updatepost             PUT    /posts/:id                        browser  posts#updatepost             DELETE /posts/:id                        browser  posts#destroypostComments     GET    /posts/:post_id/comments          browser  posts/comments#indexbuildPostComment GET    /posts/:post_id/comments/build    browser  posts/comments#buildpostComments     POST   /posts/:post_id/comments          browser  posts/comments#createpostComment      GET    /posts/:post_id/comments/:id      browser  posts/comments#showeditPostComment  GET    /posts/:post_id/comments/:id/edit browser  posts/comments#editpostComment      PATCH  /posts/:post_id/comments/:id      browser  posts/comments#updatepostComment      PUT    /posts/:post_id/comments/:id      browser  posts/comments#updatepostComment      DELETE /posts/:post_id/comments/:id      browser  posts/comments#destroy

We see that each of these routes scopes the posts to a comments ID.

For the first one, we will invoke the controller index action, but we will pass in a post_id.

This implies that we would display all the comments for that individual posts only.

The same scoping applies for all these routes.

Pipelines#

We have come quite a long way in this guide without talking about one of the first lines we saw in the router. It's time to fix that.

Pipelines are a series of plugs that can be attached to specific scopes.

Routes are defined inside scopes and scopes may pipe through multiple pipelines.

Once a route matches, Nodos invokes all plugs defined in all pipelines associated to that route.

For example, accessing "/" will pipe through the :browser pipeline, consequently invoking all of its plugs.

pipelines:  browser:    - '@nodosjs/view-extension/fetchFlash'    - '@nodosjs/view-extension/protectFromForgery'

Nodos defines two pipelines by default, :browser and :api, which can be used for a number of common tasks.

In turn we can customize them as well as create new pipelines to meet our needs.

The :browser and :api Pipelines#

As their names suggest, the :browser pipeline prepares for routes which render requests for a browser.

The :api pipeline prepares for routes which produce data for an api.

The :browser pipeline has 2 plugs:

'@nodosjs/view-extension/fetchFlash'

'@nodosjs/view-extension/protectFromForgery'

The router invokes a pipeline on a route defined within a scope.

Creating New Pipelines#

Nodos allows us to create our own custom pipelines anywhere in the router.

To do so, we create a new middleware and add to routes.yml

- app/     middlewares/       yourMiddlewares.js
pipelines:  browser:    - '@nodosjs/view-extension/fetchFlash'    - '@nodosjs/view-extension/protectFromForgery'    - yourMiddlewares
  api:    - example/setLocale    - example/setLocale
scopes:  - name: api    pipeline: api    routes:      - resources: users  - name: /    pipeline: browser    root: true    routes:      - resources: users      - resources:          name: posts          routes:            - resources: comments

Right now when the server accepts a request, the request will always first pass through the plugs in our Endpoint, after which it will attempt to match on the path and HTTP verb.

Let's say that the request matches our first route: a GET to / .

The router will first pipe that request through the :browser pipeline before it dispatches the request to the contoller index action.