2.2.1 • Published 7 years ago

express-routes-dispatcher v2.2.1

Weekly downloads
1
License
MIT
Repository
github
Last release
7 years ago

JSON based routing for Node.js

npm version Dependency Status Travis Build Status Appveyor Build Status bitHound Overall Score Codacy Badge

JSON based MVC routing using express and twig as template engine.

In this implementation, the routing is based on JSON format, which is a map from an URL path to a controller (Controller) for processing the request, apply it to data (Model) and finally to a template for visualization a result (View).

The format is similar to the syntax of Symfony YAML based Routing.

  1. Installation
  2. Usage
  3. Class Router
  4. Writing routes
  5. Writing controllers
  6. Writing templates
  7. Demo
  8. Tests
  9. License

Installation

$ npm install express-routes-dispatcher --save

or

$ yarn add express-routes-dispatcher

Usage

The Router allows you to organize simple and clear MVC-architecture in your Node.js application. Structure of directories can be the next:

app/                          // Application root.
 ├─ modules/                  // The directory containing folders of modules.
 │   ├─ Users/                // Module "Users"
 │   │   ├─ controllers/      // Controllers of the module.
 │   │   ├─ models/           // Models of the module.
 │   │   ├─ views/            // Templates such as pages, partials or blocks (BEM) of the module.
 │   │   └─ routing.js        // Routing of the module.
 │   └─ •••                   // Other modules.
 ├─ views/                    // Common templates such as static pages, partials or blocks (BEM).
 ├─ config.js                 // Config file.
 ├─ index.js                  // The entry point of the application.
 └─ routes.js                 // Base routing file. Includes common static pages and routing files of modules.

The entry point of the application is index.js. It processes all HTTP-requests.

File routes.js describes the URLs, controllers for processing requests by this URLs and templates to returning response data by the controller.

See the example of application.

Class Router

The main class allowing to create and to start router of your application.

Constructor

new Router(routes, options) returns instance of the Router.

ParameterTypeDefaultDescription
routesObjectRequired. Object with routes description.
optionsObjectAdditional options.
options.baseDirString__dirnameBase directory to resolve relative paths, such as publicDir, viewsDir and paths of routes from routes.
options.debugBooleanfalseIf true the additional route http://localhost:3000/__routes__/ with map of all routes in JSON-format is available.
options.hostString'localhost'A domain name or IP address of the server.
options.portNumber3000Port of the server.
options.protocolString'http'Protocol to use.
options.publicDirString'public'Public directory.
options.publicPathString'/'URL prefix to access to the public directory.
options.viewsDirString'views'A directory for the application's views.
import Router from 'express-routes-dispatcher';
import routes from 'routes.js';

const router = new Router(routes);

Methods

start(cb) starts and returns instance of Node.js server. Use this instance to stop server by method close().

Function cb will be called after successful starting.

const server = router.start(({ host, port, protocol }) => {
    console.log(`Server on ${protocol}://${host}:${port} was started.`);
}); // -> "Server on http://localhost:3000 was started."

close(cb) stops server.

const server = router.start();

/* ... */

server.close(({ host, port, protocol }) => {
    console.log(`Server on ${protocol}://${host}:${port} was stoped.`);
}); // -> "Server on http://localhost:3000 was stoped."

Writing routes

A routes map is an object with routes names as keys and object of routes descriptions as values.

Formal syntax

/* Inline routing description */

{
    <route name>: {
        path: <URL>,

        controller: <a path to the controller function>,
        defaults: {
            _format: <the format of a response>,
            _template: <a path to the template>,
            <pairs 'key-value' to define default values of parameters from the path>,
        },
        methods: <an array of allowed methods for requests>,
        requirements: {
            <pairs 'key-value' to define requirements for values of parameters from the path>,
        },
    },
    ...
}

<route name> is a string. It should be unique, otherwise, a last declared route with the same name will override earlier ones.

ParameterTypeDefaultDescription
pathStringRequired. A pattern of URL path includes dynamic params enclosed in braces. For example, /user/{id}/.
controllerStringA path to the controller function.
defaultsObjectAn object containing the following options:
defaults._formatString'json'The format of the response.
defaults._templateStringA path to template.
defaults.<param>Number|StringDefault values of dynamic params from path.
methodsArray\<String>['get', 'post']An array of allowed methods for requests. Available values you can find here.
requirementsObject{}An object containing the following options:
requirements.<param>StringRequirements for dynamic params from path.
/* External routing description */

{
    <routes branch name>: {
        resource: <a path to the file of external routing description>,

        prefix: <prefix for parameter 'path' of plugged routes>,
    },
    ...
}

<routes branch name> is a string. It should be also unique.

ParameterTypeDefaultDescription
resourceStringRequired. A path to the file of external routing description.
prefixStringPrefix for parameter 'path' of plugged routes.

Writing controllers

Controller is a function which accepts as a parameter the object request and returns data object. This data will be able in the template.

Example

/* controller.js */

module.exports = (request) => {
    const { params: { id } } = request;

    return {
        data: {
            id: id,
        },
    };
};
{# index.twig #}

<p>Parameter "id" from URL is {{ data.id }}</p>

Writing templates

Twig is a powerful template engine. More about it you can read in official documentation.

For all templates are available some global variables and functions.

Twig constants

__route is an object which contains parameters of the current route.

ParameterTypeDescription
__route.hostStringHostname.
__route.nameStringName of the route. You can use it for example to detect a current item of the menu.
__route.paramsObjectObject with parameters geted from the URL.
__route.pathStringThe path part of the route.
__route.protocol'http'|'https'Protocol.
__route.queryObjectObject with GET-params from the URL.
__route.subdomainsArrayArray of subdomains.
__route.urlStringThe whole request URL includes GET-params.

Example:

{% if (__route.name == 'main') %}
    <span>Main page</span>
{% else %}
    <a href="{{ path('main') }}">Main page</a>
{% endif %}

Twig tags

render is a tag which can render a controller inside another one.

Syntax:

{% render <controller> with <params> %}
ParameterTypeDescription
controllerStringRequired. A path to the controller function.
paramsObjectAdditional parameters.
options.templateStringRequired. A path to the template.

Example:

{# views/index.twig #}

<h1>Page template</h1>

{% render 'controller/partials' with {
    template: 'views/partials.twig',
}) %}
/* controller/partials.js */

module.exports = () => {
    return {
        data: {
            foo: 'baz',
        },
    };
};
{# views/partials.twig #}

<h2>Partials template</h2>

<p>foo: {{ data.foo }}</p>

In final HTML document we will get:

<h1>Page template</h1>

<h2>Partials template</h2>

<p>foo: baz</p>

Twig functions

path(name, options) is a function returns a generated URL by route name. Accepted parameters:

ParameterTypeDescription
nameStringRequired. Name of routing to generate URL.
optionsObjectAdditional options.
options.hashStringFragment, separated from the preceding part by a hash #.
options.paramsObject'Key-value' pairs to define values of parameters for the path.
options.queryObject'Key-value' pairs to define values of GET-parameters.

Example:

/* routes.js */

module.exports = {
    profile: {
        path: '/users/profile/{id}/',
    },
};
{# views/pages/index.twig #}

<a href="{{ path('profile', {
    hash: 'name',
    params: {
        id: '1a2s564ws',
    },
    query: {
        tab: 'info',
    },
}) }}">My profile</a>

In a browser you'll see:

<a href="/users/profile/1a2s564ws/?tab=info#info">My profile</a>

Demo

You can try it on the example application. To launch:

$ git clone https://github.com/ahtohbi4/express-routes-dispatcher.git
$ cd express-routes-dispatcher
$ yarn install
$ yarn start

Then open http://localhost:3000 in your favorite browser.

:warning: The demo application uses CSS Grid Layout.

Tests

$ git clone https://github.com/ahtohbi4/express-routes-dispatcher.git
$ cd express-routes-dispatcher
$ yarn install
$ yarn test

License

MIT © Alexander Antonov alexandr-post@yandex.ru