1.0.2 • Published 2 years ago

tashfin v1.0.2

Weekly downloads
4
License
ISC
Repository
-
Last release
2 years ago

Tashfin is NodeJS framework that takes the routing and modularity of ZinkyJS and removes all other aspects.

So in TashfinJS we don't have hooks, we put away the chain of responsability of ZinkyJS and ExpressJS. Only one function is called per request.

The global idea of TashfinJS is resumed in these points:

  • Super Minimalistic, even more minimalistic than ExpressJS, and has no opinion on what you should use as DB or Template Engine, and whether to SSR or to CSR.
  • It's all about routing, The one thing that TashfinJS organises is routing, that saves you from having huge files of routing and all the problems that can result of that.
  • Use things only when you need them, making code more predictable by avoiding the chain of hooks that mutates the data through the process.

Installation

npm i tashfin

Simple Example

  const { listen } = require("tashfin");
  const homeModule = {
    GET_root: (req, res) => res.end("Hello World")
  }

  const logRequest = true;
  const modules =  {
    "": homeModule
  };

  listen({modules, logRequest});

This will start a server and listen to port 3000 and return "Hello World" on every GET request

Zinky Routing Revision

Since TashfinJS follows the same routing concept of ZinkyJS, Let's make a little revision on how ZinkyJS routing work.

This is a typical route:

/users/activate/12353

This is interpreted in ZinkyJS as:

  • users: module,
  • activate: action,
  • [12353]: params

To match that route, we must have this code:

app.js

const { listen } = require("tashfin");
const users = require("./app_modules/users");

const logRequest = true;
const modules =  { users };

listen({modules, logRequest});

app_modules/users/index.js

const GET_activate = (req, res, id) => res.end(`You activated user with id: ${id}`);

module.exports = { GET_activate }

Routing Fallbacks

As ZinkyJS, TashfinJS falls back to alternative functions if the route does not find its typical operation (the one that fits the exact module and action).

The fallback process in essence:

  • If the action is not found in the module, it looks for root in the module, and puts action as first param.
  • If root of module or module are not found, it looks for "" (home) module, and puts the not found module as action.
  • If the new action is not found in home module falls back to root in home module, and puts all url parts (split by /) as params.

If that wasn't clear enough, here are some their examples.

Action Not Found

Taking the last example, we could have made the content of users module file as following:

app_modules/users/index.js

const GET_root = (req, res, whatToDo, id) => res.end(`You did ${whatToDo} user with id: ${id}`);

module.exports = { GET_root }

In this case, TashfinJS does not find GET_activate, so it looks for GET_root.

Module Root or Module Not Found

If action is not found and GET_root in the module does not exist, the interpretation becomes as follow:

  • "": module (home)
  • users: action
  • [activate, 12353]: params

And to match that, we have to add a home module that contains GET_users. So we have:

app.js

const { listen } = require("tashfin");
const home = require("./app_modules/home");

const logRequest = true;
const modules =  { "": home };

listen({modules, logRequest});

app_modules/home/index.js

const GET_users = (req, res, whatToDo, id) => res.end(`You did ${whatToDo} user with id: ${id}`);

module.exports = { GET_root }

New Action Not in Home Module

This fallback is the last one and it points to GET_root in home module, and everything in the route is considered as params. So

app_modules/home/index.js

const GET_root = (req, res, type, whatToDo, id) => res.end(`You did ${whatToDo} one of ${type} with id: ${id}`);

module.exports = { GET_root }

Don't forget to test those codes.

The last fallback prevents server from returning 404 Not Found, if a home GET_root exists. If you want to stop this behavior add noHomeRoot to Tashfin options. as following:

app.js

const { listen } = require("tashfin");
const home = require("./app_modules/home");

const logRequest = true;
const noHomeRoot = true;
const modules =  { "": home };

listen({modules, logRequest, noHomeRoot});

No Params Action

In many cases, you'll want to make /somethings to get the list and /somethings/123 to get one thing by its id. If you restrict yourself to the rules seen above, you'll find yourself making some annoying if conditions to separate the logic. Luckily, as ZinkyJS did, TashfinJS gives a way to do that simply.

  • GET_$root: Runs if there is no params
  • GET_root: Runs if there is params or GET_$root does not exist.

So we could have that in users for example:

app_modules/users/index.js

const { res.json } = require("tashfin");

const GET_$root = (req, res) => res.json([
  { name: "Omar", age: 32 },
  { name: "Yusuf", age: 50 }
]);

const GET_root = (req, res, id) => res.json({ id, name: "Omar", age: 32 });

module.exports = { GET_root }

Operation Arguments

Each operation takes these arguments:

  • req: The http.ClientRequest passed by NodeJS.
  • res: An enhanced version of The http.ServerResponse passed by NodeJS.
  • Params: The operation params.

TashfinJS Helpers

It made available some helpers, to simplify some actions that are achieved using req and res in ZinkyJS.

Those helpers are imported directly from tashfin.

getQuery

Returns the query string of the request as json object.

Eg:

const { getQuery } = require("tashfin");

const GET_$root = (req) => {
  const query = getQuery(req.url);
  console.log(query);
  // for /users?role="admin", logs: {role: "admin"}
  return "ok";
}

module.exports = { GET_root }

getPath

Returns the path of url. Especially useful when url contains query string.

Eg:

const { getPath } = require("tashfin");

const GET_$root = (req) => {
  const path = getPath(req.url);
  console.log(path);
  // for /users?role="admin", logs: /users
  return "ok" 
}

module.exports = { GET_root }

parseBody

Returns the parsed body of the request.

Eg:

const { parseBody } = require("tashfin");

const POST_root = (req) => {
  const body = parseBody(req);
  return "ok" 
}

module.exports = { GET_root }

res.json

Responds with a json object and setting the corresponding headers.

const GET_root = (req, res, id) => res.json({ id, name: "Yusuf", age: 50 });

module.exports = { GET_root }

res.redir

redirects to a given location.

Eg:

const GET_root = (req, res) => res.redir("/dashboard") 
// redirects to "/dashboard"

module.exports = { GET_root }

res.reload

Reloads the referer. Can take an alternative path, in case the referer does not exist.

Eg:

const GET_root = (req, res) => res.reload("/dashboard") 
// reloads the page or go to "/dashboard"

module.exports = { GET_root }

res.asFile

Sends file content with its corresponding mime type.

Eg:

const GET_root = (req, res) => {
  const fileContent // you bring by some code
  const ext // you bring by some code
  return res.asFile(fileContent, ext);
}

module.exports = { GET_root }

res.file

If you didn't like you bring by some code, here is what will help you.

Eg:

const GET_root = (req, res) => {
  const filePath = "the/path/of/your/file.pdf"
  return res.asFile(filePath);
}

module.exports = { GET_root }

resDownload

Returns the headers that allow to download the file in given path.

Eg:

const GET_root = (req, res) => {
  const filePath = "the/path/of/your/file.pdf"
  return res.download(filePath);
}

module.exports = { GET_root }

TashfinJS options

Here are the options that are passed to Tashfin init.

onError

A function to run when operation fails.

logRequest

A boolean to set whether or not log requests in the console.

defaultHeaders

A function takes req as argument and returns an object with the default headers and theirs values.

logRequestDate

A boolean to set whether or not log requests date in the console.

noHomeRoot

A boolean if set to true, prevents falling back to home module root.

Featured Libraries

Check these libraries to make your life even easier.

1.0.2

2 years ago

1.0.1

2 years ago

1.0.0

3 years ago

0.1.4

3 years ago

0.1.3

4 years ago

0.1.2

4 years ago

0.1.1

4 years ago