tashfin
v1.0.2
Published
ZinkyJS but functional
Downloads
2
Maintainers
Readme
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 paramsGET_root
: Runs if there is params orGET_$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
: Thehttp.ClientRequest
passed by NodeJS.res
: An enhanced version of Thehttp.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.