npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@ah_naf/noderoute

v2.2.0

Published

A lightweight, flexible HTTP server framework for Node.js.

Downloads

3

Readme

NodeRoute

Overview

The NodeRoute package is a lightweight, flexible HTTP server framework for Node.js, designed to simplify route management, middleware integration, and static file serving. It allows developers to define routes, handle different HTTP methods, and serve static files with ease. NodeRoute is inspired by popular frameworks like Express.js, but it aims to provide a simpler and more modular approach.

Key Features

  1. Route Management: Define routes with support for GET, POST, PUT, and DELETE methods.
  2. Middleware Support: Apply global, route-based global, and route-based local middlewares for request handling.
  3. Static File Serving: Serve static files from specified directories.
  4. Customizable Response Methods: Extend response object with custom methods like sendFile, json, and status.
  5. Dynamic URL Parameter Extraction: Extract and use URL parameters in request handlers.
  6. Configurable Options: Customize server behavior with options like logging, default headers, body size limits, and custom 404 pages.
  7. Route-Specific Options: Override global options for specific routes.
  8. Middleware Chaining: Add middlewares before specific HTTP method handlers.
  9. File Upload Handling: Support for single binary file uploads through req.file.
  10. Request Timeout: Configurable timeout for requests to prevent long-running operations.

How It Works

Core Classes

1. NodeRoute

  • Manages the HTTP server, global middlewares, and routes.
  • Listens for incoming requests and delegates them to the appropriate route handlers.

2. Route

  • Defines and manages individual routes and their handlers.
  • Supports middleware chaining and static file route setup.

Methods and Usage

NodeRoute

  • Constructor: Initializes the server with optional configurations.

    const server = new NodeRoute({
      custom404Path: path.join(__dirname, "public", "custom_404.html"),
      defaultHeaders: { "X-Powered-By": "NodeRoute" },
      enableLogging: true,
      bodySizeLimit: 1024, // 1 KB
      timeout: 2000, // 2 seconds
    });
  • use(middleware): Adds a global middleware.

    server.use((req, res, next) => {
      console.log(`${req.method} ${req.url}`);
      next();
    });
  • route(path, options): Defines a new route with optional configurations.

    const publicRoute = server.route("/public", { bodySizeLimit: 2048 });
  • listen(port, callback): Starts the server on the specified port.

    server.listen(3000, () => {
      console.log("Server is listening on port 3000");
    });

Route

  • get(...handlers): Defines a GET handler for the route.

    publicRoute.get((req, res) => {
      res.status(200).json({ message: "Successfully accessed public route" });
    });
  • post(...handlers): Defines a POST handler for the route.

    publicRoute.post((req, res) => {
      const body = req.body;
      res
        .status(201)
        .json({ message: "Successfully received POST data", data: body });
    });
  • put(...handlers): Defines a PUT handler for the route.

  • delete(...handlers): Defines a DELETE handler for the route.

  • use(...middlewares): Adds middlewares specific to the route.

    publicRoute.use((req, res, next) => {
      console.log(`Middleware for ${req.method} ${req.url}`);
      next();
    });
  • sendStatic(staticDir, options): Serves static files from the specified directory.

    server.route("/").sendStatic(path.join(__dirname, "public"));

Middleware Levels

  1. Global Middleware: Applied to all routes.

    server.use((req, res, next) => {
      console.log(`Global middleware: ${req.method} ${req.url}`);
      next();
    });
  2. Route-Based Global Middleware: Applied to all handlers within a specific route.

    const publicRoute = server.route("/public");
    publicRoute.use((req, res, next) => {
      console.log(`Route-based global middleware: ${req.method} ${req.url}`);
      next();
    });
  3. Route-Based Local Middleware: Applied before specific HTTP method handlers.

    publicRoute.get(
      (req, res, next) => {
        console.log("Local middleware for GET /public");
        next();
      },
      (req, res) => {
        res.status(200).json({ message: "Successfully accessed public route" });
      }
    );

Installing and Using NodeRoute

NodeRoute is available on the npm registry, making it easy to install and use in your Node.js projects. Follow the steps below to get started.

Installation

To install NodeRoute, you can use npm or yarn. Run the following command in your project directory:

npm install @ah_naf/noderoute

Or, if you prefer using yarn:

yarn add @ah_naf/noderoute

Example Usage

Here’s a complete example demonstrating how to use NodeRoute in a Node.js application.

Project Structure

Create a project structure like this:

my-noderoute-app/
├── public/
│   ├── index.html
│   └── custom_404.html
├── index.js
├── package.json

Setting Up index.js

In your index.js file, set up the NodeRoute server, define routes, and add middlewares:

const path = require("path");
const NodeRoute = require("@ah_naf/noderoute");

const server = new NodeRoute({
  custom404Path: path.join(__dirname, "public", "custom_404.html"),
  defaultHeaders: { "X-Powered-By": "NodeRoute" },
  enableLogging: true,
  bodySizeLimit: 1024, // 1 KB
  timeout: 2000, // 2 seconds
});

// Global middleware
server.use((req, res, next) => {
  console.log(`Global middleware: ${req.method} ${req.url}`);
  next();
});

const publicRoute = server.route("/public", { bodySizeLimit: 2048 });

// Route-based global middleware
publicRoute.use((req, res, next) => {
  console.log(`Route-based global middleware: ${req.method} ${req.url}`);
  next();
});

// Route-based local middleware
publicRoute.get(
  (req, res, next) => {
    console.log("Local middleware for GET /public");
    next();
  },
  (req, res) => {
    res.status(200).json({ message: "Successfully accessed public route" });
  }
);

publicRoute.post((req, res) => {
  const body = req.body;
  res
    .status(201)
    .json({ message: "Successfully received POST data", data: body });
});

// Serve static files from the 'public' directory
server.route("/").sendStatic(path.join(__dirname, "public"));

server.listen(3000, () => {
  console.log("Server is listening on port 3000");
});

public/index.html

Create a simple HTML file in the public directory:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>NodeRoute Example</title>
  </head>
  <body>
    <h1>Welcome to NodeRoute</h1>
    <p>This is a static file served by NodeRoute.</p>
  </body>
</html>

public/custom_404.html

Create a custom 404 error page:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>404 Not Found</title>
  </head>
  <body>
    <h1>404 - Page Not Found</h1>
    <p>Sorry, the page you are looking for does not exist.</p>
  </body>
</html>

Running the Server

To start the server, run the following command in your project directory:

node index.js

You should see the following output:

Server is listening on port 3000

Accessing the Server

Open your browser and navigate to http://localhost:3000. You should see the content of public/index.html.

To test the route-based middleware and handlers, navigate to http://localhost:3000/public.

Options

  • custom404Path: Path to a custom 404 page.
  • defaultHeaders: Headers to be added to all responses.
  • enableLogging: Boolean to enable/disable logging. Logs method, URL, status code, and time taken for the request.
  • bodySizeLimit: Maximum allowed body size for incoming requests.
  • timeout: Maximum time allowed for a request before it is terminated.
  • Route-Specific Options: Override global options for specific routes (e.g., bodySizeLimit).

File Upload Handling

NodeRoute supports handling single binary file uploads through the req.file stream. This allows for efficient handling of file

uploads without loading the entire file into memory.

Example of handling a file upload:

const fs = require("fs");
const uploadRoute = server.route("/upload");

uploadRoute.post((req, res) => {
  const filePath = path.join(__dirname, "uploaded_file.png");
  const writableStream = fs.createWriteStream(filePath);

  req.file.pipe(writableStream);

  writableStream.on("finish", () => {
    res.status(200).json({ message: "File uploaded successfully" });
  });

  writableStream.on("error", (error) => {
    console.error("Error writing file:", error);
    res.status(500).json({ error: "Internal Server Error" });
  });
});

In this example, the uploaded file is streamed to the server and saved as uploaded_file.png in the current directory. This method ensures that the server can handle large file uploads efficiently without exhausting memory.

Example with Timeout Route

Here’s an example that demonstrates how to use the timeout option:

const path = require("path");
const NodeRoute = require("@ah_naf/noderoute");

const server = new NodeRoute({
  custom404Path: path.join(__dirname, "public", "custom_404.html"),
  defaultHeaders: { "X-Powered-By": "NodeRoute" },
  enableLogging: true,
  bodySizeLimit: 1024, // 1 KB
  timeout: 2000, // 2 seconds
});

const timeoutRoute = server.route("/api/timeout");

timeoutRoute.get((req, res) => {
  // Simulate a long-running operation
  setTimeout(() => {
    res.status(200).json({ message: "This request took a long time" });
  }, 3000); // This will exceed the server timeout
});

server.listen(3000, () => {
  console.log("Server is listening on port 3000");
});