@ah_naf/noderoute
v2.2.0
Published
A lightweight, flexible HTTP server framework for Node.js.
Downloads
3
Maintainers
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
- Route Management: Define routes with support for GET, POST, PUT, and DELETE methods.
- Middleware Support: Apply global, route-based global, and route-based local middlewares for request handling.
- Static File Serving: Serve static files from specified directories.
- Customizable Response Methods: Extend response object with custom methods like
sendFile
,json
, andstatus
. - Dynamic URL Parameter Extraction: Extract and use URL parameters in request handlers.
- Configurable Options: Customize server behavior with options like logging, default headers, body size limits, and custom 404 pages.
- Route-Specific Options: Override global options for specific routes.
- Middleware Chaining: Add middlewares before specific HTTP method handlers.
- File Upload Handling: Support for single binary file uploads through
req.file
. - 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
Global Middleware: Applied to all routes.
server.use((req, res, next) => { console.log(`Global middleware: ${req.method} ${req.url}`); next(); });
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(); });
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");
});