Routing
Last updated: 4 - 5 - 2019

ZinkyJS's routing style is one of the awesome features that make this framework special. Unlike most of other frameworks in which you attach functions to routes, in ZinkyJS, routes know automatically which function to run. This makes the project architecture more clear, indeed, by reading the url you know where the code handling the request is located in your project.

Convention

As said earlier, in ZinkyJS apps, functions are attached automatically to routes. And they are organized in a way that lets you locate the code handling the request easily. This idea requires making some conventions, to become possible.

ZinkyJS splits every request path by "/" into parts, each one of them has its meaning:

  1. First part:
    Refers to the module
  2. Second part:
    Refers to the action (function) in the module
  3. Rest of parts:
    Are read as parameters grouped in an array

Eg:

 /users/create/Omar/premium
translates to:
  "users": module name
  "create": action
  "Omar": first parameter
  "premium": second parameter

Functions Code

Every function that matches a route resides in the "index.js" of its module.

A function name is composed of two parts separated by an underscore ("_"):

  1. Method:
    GET, POST, PUT... (uppercase)
  2. Action:
    The request action (saw above)

Eg:

 GET /users/create/Omar/premium
The function that handles this request is 'GET_create' located in 'app_modules/users/index.js'

In ZinkyJS, these functions are called operations

So:

 GET /users/create/Omar/premium
translates to:
  "users": module name
  "create": action
  "GET_create": operation
  "Omar": first parameter
  "premium": second parameter

So, let's write the code:

1. Create the "users" module by running:

zinky -M users

2. Add this method(operation) to the class in "app_modules/users/index.js":

 GET_create(req, res) {
  res.end(`create user with name: ${req.params[0]} as: ${req.params[1]}`);
}

3. Visit localhost:3000/users/create/Omar/premium, and see the result!

Direct Responder

Instead of putting the response in res.end or req.json, you can just return it in the function as you used to do in any other function.

So instead of that:

 GET_create(req, res) {
  res.end(`create user with name: ${req.params[0]} as: ${req.params[1]}`);
}

You can do this:

 GET_create(req, res) {
  return `create user with name: ${req.params[0]} as: ${req.params[1]}`;
}

This is very useful, when you have a function that acts as an operation and as a helper at the same time.

Params, Query & Body

In addition to params, we can send request values just as we do traditionally:

- Query:

 // for: GET /users/create/Omar/premium?gender=male
GET_create(req, res) {
  req.query  // will look like: {gender: "male"}
  req.params // will look like: ['Omar', 'premium']
}

- Body: you will find the request body in req.body

Module's Root

We saw that ZinkyJS parses the url and searches for the action to know what function it should call. But sometimes, you simply don't need an action.

Imagine we want to get users. It would be sufficient to just request GET /users/, without specifying any action. ZinkyJS makes this possible by calling to root action if no action found.
So you write in "app_modules/users/index.js":

 GET_root(req, res) {
  var users = ['Mohamad', 'AbuBakr', 'Omar', 'Othman'];
  res.json(users);
}

Aliases

ZinkyJS gives the possibility to call a module by a different name than the one you gave to its folder.

If for any reason you want to replace "users" in the request by something else, we'll say "customers" for example, you will just have to add aliases property to app object, like this:

 const Zinky = require('zinky');

var app = new Zinky({
 aliases: {
    'customers': 'users'
  }
});

app.listen();

That way, any time ZinkyJS finds "customers" as module name, it will call "users" module.

Usefulness of aliases

The aliases prop is very useful as it resolves a problem we face in every ZinkyJS project.
We saw in the previous course how to make a home page, but 'www.example.com/home' is not an acceptable home page route.
A website home page should be accessible by this route 'www.example.com'.

Here comes the 'aliases' super hero to resolve that. So you tell ZinkyJS that if no module name is given, call the home module:

 const Zinky = require('zinky');

var app = new Zinky({
 aliases: {
    '': 'home'
    'customers': 'users'
  }
});

app.listen();

If Not Found

If the module or the operation does not exist, ZinkyJS will throw:
 { statusCode: 404 }

Check the error handling course for further details.

Next Course: Hooks