als-router

2.2.0 • Public • Published

als-router

als-router is a lightweight, expressive routing library for Node.js that enables you to build powerful and maintainable HTTP servers. This library focuses on high performance and flexibility, offering an intuitive API for declaring routes and handling requests.

als-router integrates seamlessly with the native Node.js HTTP server module. It allows you to define routes using standard HTTP methods and supports dynamic URL parameters, custom middleware, and complex routing capabilities. Routes are matched in the order they are defined, and each route can have its own middleware stack.

Change log

  • issue with autoend and order for running mw fixed

Installation

To use als-router, install the package via npm:

npm install als-router

Basic Usage

Here's a simple example to get you started with als-router and a native HTTP server:

const http = require("http");
const Router = require("als-router");
const router = new Router();

router.get("/", (req, res) => {
  res.writeHead(200, { "Content-Type": "text/plain" });
  res.end("Hello World");
});
router.get('/','public',{ index:true, etag:true }) // static route

const server = http.createServer((req, res) => {
  router.request(req, res);
});

server.listen(3000);

Methods

Router.env.methods is an array of HTTP methods the router should handle. By default:

Router.env.methods === ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT','PATCH'];

These methods are available on the router after its initiation. In the default case, the router will include the following methods:

const router = new Router();
router.delete(path, ...handler);
router.get(path, ...handler);
router.head(path, ...handler);
router.options(path, ...handler);
router.post(path, ...handler);
router.put(path, ...handler);
router.patch(path, ...handler);

path is a URL path and handler is a function or functions to handle the request. Here is an example:

The handler can be array/arrays of function, or functions.

const auth = (req, res, next) => {
  if (req.session.auth) return next();
  res.writeHead(302, { Location: "/login" });
  res.end();
};
const dashboard = (req, res) => res.end("Hello from dashboard");
router.get("/dashboard", auth, dashboard);

If there are multiple functions, you must call next, unless the autoEnd parameter is set to true (false by default).

autoEnd

Router.env.autoEnd determines whether the execution should automatically be considered complete if the next callback is not explicitly called within a middleware function. If set to true, the function will automatically end the execution and resolve the associated Promise when the end of the middleware chain is reached without a next call.

The default value is false, which requires each middleware function to explicitly call next to continue the execution or to handle it as complete. This parameter provides flexibility in managing asynchronous operations within the middleware chain, ensuring that developers have control over the flow based on specific application needs.

Except the last function, which will wait for promise resolve or will respond with status 408 if it times out.

Routing (path)

The Router supports regular and dynamic routes which may include parameters or wildcards. Here's an example:

router.get("/user/{id}", (req, res) => {
  req.params.id;
});

router.post("/user/{id}/profile/{section}/*", (req, res) => {
  const { id, section } = req.params;
});

router.put("/user/{id}/files/**", (req, res) => {
  const { id, rest:filepath } = req.params;
});

Get more information on als-path-to-regexp.

Static routes

als-server supports static routes out of the box. All you need is to provide rootDir to env.

Router.env.rootDir = __dirname
const options = {
  // (Boolean,default:false). Serve 'index.html' files for directory routes
  index:false, 
  // (Boolean,default:false). Sets Content-Disposition to attachment for downloads or inline to open in the browser.
  download: false,
  // (String, optional): Adds charset to Content-Type.
  charset,
  // (Boolean, default: true): Adds Last-Modified and ETag for client-side caching.
  etag:true,
  // (Number, optional): Specifies the maximum amount of time (in seconds) that the resource is considered fresh.
  maxAge:60*60*60,
  // (Boolean, default: false): Requires that all copies of the response be revalidated with the server before use.
  noCache:false,
  // (Boolean, default: false): Prohibits any caching of the response.
  noStore:false,
  // (String, optional): Indicates where the response may be cached (in public proxies or only in the user’s browser). Defaults to public if any other value is passed.public,
  public:'public',
}

router.get('/','public',options)

If directory not exists, it will be created.

httpErrorHandler and errors

Router.env.httpErrorHandler is a function with 3 parameters: res, code, message. By default, als-http-error handler is used, but you can change it to your own.

The router handles the following statuses:

  • 403 Forbidden: Returned when the requested URL is not valid or not allowed. This can happen if the path in the request URL is malformed.
  • 404 Not Found: No route matches the request URL. This status is sent when a route cannot be found to handle the request.
  • 405 Method Not Allowed: The HTTP method specified in the request is not supported by the route. This can happen if a specific route exists but does not support that method.
  • 500 Internal Server Error: An unexpected error occurs within a route handler or middleware. This status is used as a general error response.
  • 501 Not Implemented: The HTTP method used in the request is not implemented by the router. Check Router.env.methods to see which methods are supported.
  • 408 Request Timeout: Sent when a request does not complete within the time specified by Router.env.timeout. This ensures that resources are not held indefinitely.

Middleware

There are two types of middleware (mw): global and local. The global mw will apply to all instances of Router, while local ones will apply only to a specific Router instance. To set mw, use: router.use(middleware, [global]).

Example:

function redirectMiddleware(req, res, next) {
   res.redirect = function (path) {
      res.writeHead(302, { 'Location': path });
      res.end();
   };

   res.redirectBack = function () {
      res.redirect(req.headers.referer || '/');
   };
   next();
}

function statusMw(req, res, next) {
  res.status = function status(code) {
      res.statusCode = code;
      return res;
  };
  next();
}

const router1 = new Router('/');
router1.use(statusMw); // will apply only for routes in this router
router1.use(redirectMiddleware, true); // will apply to all routes 
const router2 = new Router('/dashboard');

You can add local mw, also by adding mw as a second parameter:

const router = new Router('/', [statusMw, redirectMiddleware]);

In the example above, mw is added as local.

The order of calling mw

First, global mw is called, by order of adding, and then the local mw.

Environment Parameters

als-router allows you to customize its behavior through environment parameters. Here's a list of the parameters you can configure:

  • methods: An array of HTTP methods the router should handle.
  • autoEnd: A boolean that determines whether the router should automatically end the response if next is not called.
  • logger: A function for logging errors or other information.
  • timeout: The maximum time (in milliseconds) to wait for a request to be handled before timing out.
  • methodName: The query parameter used to override the HTTP method (useful for clients that can't send all HTTP methods).
  • httpErrorHandler: A function to handle HTTP errors with parameters for the response object, status code, and message.

Logger

Router.env.logger is a function used to log errors and other important information during the operation of routes. By default, Router.env.logger is set to console.log, which logs to the standard output.

However, if you need more sophisticated logging capabilities, such as logging to a file or integrating with a logging service, you can replace the default logger. Simply assign a new function to Router.env.logger that accepts the same parameters as console.log.

For example, to integrate a custom logger, you might set it like this:

const customLogger = (message, ...optionalParams) => {
  // Implement logging logic here
  console.log(message, ...optionalParams);
};

Router.env.logger = customLogger;

This function will be called whenever there is an error within any route handler, ensuring that all errors are logged consistently, providing better visibility for debugging and monitoring your application's health.

router.self

router.self returns Router class

Package Sidebar

Install

npm i als-router

Weekly Downloads

25

Version

2.2.0

License

ISC

Unpacked Size

59.6 kB

Total Files

15

Last publish

Collaborators

  • alexsorkin