LiteNode's logo

LiteNode

Docs GitHub logo
▶ Usage

Documentation

Routing

LiteNode offers a comprehensive routing system that handles HTTP methods, route parameters, wildcards, and debugging features.

Adding Routes

You can add routes for different HTTP methods (GET, POST, PUT, DELETE, PATCH):

Get

Signature:

get(routePath: string, ...handlers: RouteHandler[]): LiteNode

Defines a route with the GET method.

Example:

// Define a GET route with a route handler function
app.get("/users", (req, res) => {
    res.end("List of users")
})

// Define a GET route with middleware and a route handler function
app.get("/users/:id", authenticate, (req, res) => {
    const userId = req.params.id
    res.end(`User ID: ${userId}`)
})

Post

Signature:

post(routePath: string, ...handlers: (RouteHandler | number)[]): LiteNode

Defines a route with the POST method.

Example:

// Define a POST route with a route handler function
app.post("/users", (req, res) => {
    // The parsed body
    const data = req.body
    // Logic to create a new user
    res.end("User created successfully")
})

// Access the parsed body directly
app.post(
    "/users",
    (req, res, data) => {
        // 'data' represents the parsed body of the request
        // You can now use 'data' directly in your code
    },
    2 // Set a maximum request size limit of 2 MB (optional, default is 1MB)
)

For detailed documentation about the post method, including complete examples, please refer to the Body Parsing page.


Put

Signature:

put(routePath: string, ...handlers: (RouteHandler | number)[]): LiteNode

Defines a route with the PUT method.

Example:

// Define a PUT route with a route handler function
app.put("/users/:id", (req, res) => {
    const userId = req.params.id
    const userData = req.body // Access the parsed request body
    // Logic to update user with ID userId
    res.end(`User with ID ${userId} updated successfully`)
})

// Example with custom request size limit
app.put(
    "/documents/:id",
    (req, res) => {
        const documentId = req.params.id
        const updatedContent = req.body
        // Logic to update document with the new content
        res.json({ success: true, message: `Document ${documentId} updated` })
    },
    5 // Set a maximum request size limit of 5 MB for larger documents
)

Delete

Signature:

delete(routePath: string, ...handlers: (RouteHandler | number)[]): LiteNode

Defines a route with the DELETE method.

Example:

// Simple DELETE route
app.delete("/users/:id", (req, res) => {
    const userId = req.params.id
    // Logic to delete user with ID userId
    res.end(`User with ID ${userId} deleted successfully`)
})

// DELETE route with request body for bulk operations
app.delete(
    "/users",
    (req, res) => {
        const userIds = req.body.ids // Array of IDs to delete
        // Logic to delete multiple users
        res.json({ deleted: userIds.length, success: true })
    },
    2 // Set a maximum request size limit of 2 MB
)

Patch

Signature:

patch(routePath: string, ...handlers: (RouteHandler | number)[]): LiteNode

Defines a route with the PATCH method.

Example:

// Simple PATCH route
app.patch("/users/:id", (req, res) => {
    const userId = req.params.id
    const updates = req.body // Partial updates for the user
    // Logic to update specific fields of user with ID userId
    res.end(`User with ID ${userId} patched successfully`)
})

// PATCH route with larger request size limit
app.patch(
    "/articles/:id",
    (req, res) => {
        const articleId = req.params.id
        const updates = req.body
        // Logic to partially update an article
        res.json({ updated: true, articleId })
    },
    10 // Set a maximum request size limit of 10 MB for larger content
)

Any

Signature:

any(routePath: string, ...handlers: RouteHandler[]): LiteNode

Defines a route that responds to all HTTP methods (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS).

Example:

// Define a route that responds to all HTTP methods
app.any("/health", (req, res) => {
    res.json({
        status: "healthy",
        method: req.method,
    })
})

Redirect

Signature:

redirect(location: string, statusCode: number = 302): void

Initiates a redirect response to the client with the specified location URL and optional status code. If status code is not provided, it defaults to 302 (temporary redirect). This method sets the appropriate HTTP headers for the redirect response and ends the response.

You can use the redirect() method in your route handlers to make a temporary or permanent redirect.

Example:

// Route to handle redirecting to the root URL
app.get("/redirect", (req, res) => {
    res.redirect("/") // Redirect to the root URL
})

// Route to handle permanent redirect to the root URL
app.get("/redirect-permanently", (req, res) => {
    res.redirect("/", 301) // Permanent redirect (301) to the root URL
})

Status

Signature:

status(code: number): nativeRes

Set the HTTP status code and send a response in a fluent, chainable manner within your route handlers.

The method chaining ensures that the response object (nativeRes) is returned, allowing for subsequent method calls such as json or render.

Example:

// Create a new LiteNode application instance
const app = new LiteNode()

// Route to handle POST requests to "/api/data"
app.post(
    "/api/data",
    async (req, res, data) => {
        // Process data...
        res.status(200).json({ success: true, data }) // Respond with a JSON success message and the processed data
    },
    0.25 // Set maximum request size to 0.25MB = 250KB
)

// Route to handle GET requests to "/template"
app.get("/template", (req, res) => {
    // Render the "template.html" file with the provided data
    res.status(200).render("template.html", { title: "Hello, World!" })
})

Route Parameters

LiteNode utilizes parameters to enhance routing and handle dynamic data in applications.

Basic Parameters

You can define routes with parameters by using the :paramName syntax:

// Define a route to handle GET requests for user details
app.get("/user/:id", (req, res) => {
    // Extract the user ID from the request parameters
    const userId = req.params.id
    // Send a response with the user ID
    res.end(`User ID: ${userId}`)
})

Accessing http://localhost:5000/user/123 will respond with "User ID: 123".


Optional Parameters

You can make route parameters optional by adding a question mark (?) after the parameter name:

// Define a route that works with or without an ID
app.get("/users/:id?", (req, res) => {
    // Extract the ID from params (may be undefined)
    const userId = req.params.id

    if (userId) {
        res.end(`Details for user: ${userId}`)
    } else {
        res.end("List of all users")
    }
})

This route will match both /users and /users/123, making the :id parameter optional.

You can also chain multiple optional parameters:

app.get("/blog/:category?/:post?", (req, res) => {
    const { category, post } = req.params

    if (post) {
        res.end(`Showing post "${post}" in category "${category}"`)
    } else if (category) {
        res.end(`Showing all posts in category "${category}"`)
    } else {
        res.end("Showing all blog posts")
    }
})

This route will match /blog, /blog/tech, and /blog/tech/nodejs.


Query Parameters

Query parameters can be accessed via req.queryParams:

// Define a route to handle GET requests for search queries
app.get("/search", (req, res) => {
    // Extract the search query from the request query parameters
    const query = req.queryParams.get("q")
    // Send a response with the search query
    res.end(`Search query: ${query}`)
})

Wildcard Routes

LiteNode supports wildcard routes for flexible path matching:

Single Segment Wildcard

Signature:

wildcard(routePath: string, ...handlers: RouteHandler[]): LiteNode

Matches a single path segment with a wildcard. This is equivalent to appending /* to your route path.

Example:

// Match /files/any-filename (but not /files/dir/file)
app.wildcard("/files", (req, res) => {
    const filename = req.params["*"]
    res.end(`Viewing file: ${filename}`)
})

// The same route can be defined directly with the * syntax:
app.get("/files/*", (req, res) => {
    const filename = req.params["*"]
    res.end(`Viewing file: ${filename}`)
})

Catch-All Wildcard

Signature:

catchAll(routePath: string, ...handlers: RouteHandler[]): LiteNode

Matches multiple path segments with a catch-all wildcard. This is equivalent to appending /** to your route path.

Example:

// Match /api followed by any number of path segments
app.catchAll("/api", (req, res) => {
    const path = req.params["**"]
    res.json({ message: `API path: ${path}` })
})

// The same route can be defined directly with the ** syntax:
app.get("/api/**", (req, res) => {
    const path = req.params["**"]
    res.json({ message: `API path: ${path}` })
})

This will match routes like:


Combining Route Features

You can combine these routing features for more flexible URL patterns:

// Match /admin/users and /admin/users/anything
app.get("/admin/users/:file?", (req, res) => {
    const file = req.params.file

    if (file) {
        res.json({ message: `Admin viewing user: ${file}` })
    } else {
        res.json({ message: "Admin viewing all users" })
    }
})

// Complex pattern matching example
app.get("/catalog/:category?/:id?", (req, res) => {
    const { category, id } = req.params

    if (id) {
        res.json({ message: `Viewing item ${id} in ${category}` })
    } else if (category) {
        res.json({ message: `Viewing all items in ${category}` })
    } else {
        res.json({ message: "Viewing catalog home" })
    }
})

Printing the Route Tree

For debugging purposes, you can print the route tree:

// Print the route tree of the LiteNode instance
app.printTree()

This will output a hierarchical view of all registered routes, including their HTTP methods, parameters, and wildcards.

Example output:

Root
  └─ [GET] ↠  (req, res) => { res.end("Hom...
  ├─ users
    └─ [GET] ↠  (req, res) => { res.json({ ...
    ├─ :id (optional)
      └─ [GET] ↠  (req, res) => { const id = ...
  ├─ files
    ├─ * (wildcard)
      └─ [GET] ↠  (req, res) => { const file...
  ├─ api
    ├─ ** (wildcard)
      └─ [GET] ↠  (req, res) => { const path...

The tree visualization helps you understand how routes are organized and matched, making it easier to debug complex routing scenarios.

Content