LiteNode's logo

LiteNode

Docs GitHub logo
▶ Usage

Documentation

Body Parsing

LiteNode offers built-in support for parsing request bodies, streamlining the handling of JSON, URL-encoded form data, and multipart/form-data in request payloads. This functionality simplifies working with APIs and data interchange.

Accessing Request Body Data

LiteNode provides two equivalent ways to access parsed request body data:

  1. Through the req.body property inside your route handler
  2. Through the third parameter (commonly named data) in your route handler function

These methods are interchangeable and provide the same data. Choose the style that best fits your coding preferences.

// Method 1: Using req.body
app.post("/example", (req, res) => {
    const userData = req.body
    // Process data...
})

// Method 2: Using the third parameter
app.post("/example", (req, res, data) => {
    const userData = data
    // Process data...
})

Supported HTTP Methods

Body parsing is automatically enabled for the following HTTP methods:

Each method works identically with respect to body parsing, allowing you to access request data through req.body or the third parameter regardless of which HTTP method was used.

Setting Request Size Limits

You can set a size limit on the request body by adding a number parameter after your route handler. This value represents the maximum size in megabytes:

// Limit request size to 0.5MB (512KB)
app.post("/upload", handleUpload, 0.5)

// Default limit is 1MB if not specified
app.put("/update", handleUpdate)

// For larger uploads (5MB)
app.patch("/update-image", handleImageUpdate, 5)

Handling Different HTTP Methods

POST Example (Creating Resources)

app.post("/users", (req, res) => {
    const newUser = req.body
    // Create new user logic...
    res.status(201).json({ message: "User created", id: "new-user-id" })
})

PUT Example (Replacing Resources)

app.put("/users/:id", (req, res) => {
    const userId = req.params.id
    const updatedUser = req.body

    // Replace user with new data...

    res.json({
        message: `User ${userId} completely updated`,
        user: updatedUser,
    })
})

PATCH Example (Partial Updates)

app.patch("/users/:id", (req, res, data) => {
    const userId = req.params.id
    const updates = data // Using third parameter style

    // Apply partial updates to user...

    res.json({
        message: `User ${userId} partially updated`,
        updates: updates,
    })
})

DELETE Example (With Body Data)

app.delete("/users/:id", (req, res) => {
    const userId = req.params.id
    const { reason, confirmation } = req.body

    // Delete user with additional metadata...

    res.json({
        message: `User ${userId} deleted`,
        reason: reason,
    })
})

Data Format Examples

JSON

JSON Client

The provided HTML form, along with its corresponding script, is designed to collect user registration information and submit it to the server as JSON. The form includes fields for username, email, and password, all of which are required. When the user submits the form, the script prevents the default form submission, converts the form data to a JSON object, and sends it to the /register endpoint using a POST request. The script also handles and displays success or error messages based on the server's response.

<form onsubmit="handleSubmit(event)">
    <label for="username">Username:</label>
    <input type="text" id="username" name="username" required />

    <label for="email">Email:</label>
    <input type="email" id="email" name="email" required />

    <label for="password">Password:</label>
    <input type="password" id="password" name="password" required />

    <button type="submit">Register</button>
</form>

<script>
    async function handleSubmit(event) {
        event.preventDefault() // Prevent default form submission

        const form = event.target
        const formData = new FormData(form)
        const userData = Object.fromEntries(formData.entries()) // Convert form data to an object

        try {
            const response = await fetch("/register", {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                },
                body: JSON.stringify(userData),
            })

            if (!response.ok) {
                const errorData = await response.json()
                throw new Error(errorData.error || "An error occurred during registration")
            }

            const responseData = await response.json()
            alert(responseData.message) // Display success message
        } catch (error) {
            alert("Error: " + error.message) // Display error message
        }
    }
</script>

JSON Server

The server-side code defines a route to handle user registration at the /register endpoint. When a POST request is received, the server processes the request body, which is expected to be in JSON format. The server performs the following tasks:

  1. Data Extraction and Validation: Extracts username, email, and password from the request body. It validates that all required fields are present.
  2. Error Handling: If any required fields are missing, the server responds with a 400 status code and an error message indicating the missing fields.
  3. User Registration: If validation is successful, the server proceeds with the user registration process, which may involve database operations.
  4. Success Response: On successful registration, the server sends a 201 status code with a JSON response indicating that the user was registered successfully.
  5. Error Response: If an error occurs during registration, the server responds with a 400 status code and an error message detailing the issue.

Optional: The request size is limited to 0.5MB to prevent excessively large payloads.

// Define a route to handle user registration
app.post(
    "/register",
    async (req, res, data) => {
        try {
            // Simulate user registration process
            const { username, email, password } = data
            // Validate user data (e.g., check for required fields)
            if (!username || !email || !password) {
                // If any required field is missing, throw an error
                throw new Error("Missing required fields")
            }
            // If all validation passes, register the user
            // Database operations...
            res.writeHead(201, { "Content-Type": "application/json" })
            res.end(JSON.stringify({ message: "User registered successfully" }))
            // Or simply write after database operations...
            res.status(201).json({ message: "User registered successfully" })
        } catch (error) {
            // Handle any errors that occur during registration
            console.error("Error registering user:", error.message)
            res.writeHead(400, { "Content-Type": "application/json" })
            res.end(JSON.stringify({ error: error.message }))
            // Or simply write
            res.status(400).json({ error: error.message })
        }
    },
    0.5 // Set maximum request size to 0.5MB = 512KB (optional, default is 1MB)
)
Information SVG Writing:
res.writeHead(201, { "Content-Type": "application/json" })
res.end(JSON.stringify({ message: "My message" }))
Is the same as writing:
res.status(201).json({ message: "My message" })

URL-encoded form data

URL-encoded Client

The following HTML form is designed to submit data to the /create-file endpoint using URL-encoded form data. It employs bracket notation in the input names to match the expected structure on the server side.

Form Fields
  1. Title: A text input for the file's title, named file[title].
  2. Description: A textarea for the file's description, named file[description].
  3. Image URL: A URL input for the file's image URL, named file[image].
  4. Publish Date: A date input for the file's publication date, named file[publish_date].
  5. Tags: A text input for comma-separated tags associated with the file, named file[tags].
Form Attributes
Purpose

This form allows users to input and submit detailed information about a file. Each field corresponds to a specific piece of data that the server will process, utilizing the bracket notation to structure the incoming data correctly.

<form action="/create-file" method="POST" enctype="application/x-www-form-urlencoded">
    <label for="file_title">Title:</label>
    <input type="text" id="file_title" name="file[title]" required />

    <label for="file_description">Description:</label>
    <textarea id="file_description" name="file[description]" required></textarea>

    <label for="file_image">Image URL:</label>
    <input type="url" id="file_image" name="file[image]" required />

    <label for="file_publish_date">Publish Date:</label>
    <input type="date" id="file_publish_date" name="file[publish_date]" required />

    <label for="file_tags">Tags (comma-separated):</label>
    <input type="text" id="file_tags" name="file[tags]" />

    <button type="submit">Create File</button>
</form>

URL-encoded Server

The following server-side code snippet handles URL-encoded form data, demonstrating both POST and PUT methods:

// POST example
app.post("/create-file", (req, res, data) => {
    const { file } = data
    // Proceed with creating the file
    res.status(201).json({ message: "File created successfully" })
})

// PUT example
app.put("/update-file/:id", (req, res) => {
    const fileId = req.params.id
    const { file } = req.body
    // Proceed with updating the file
    res.json({ message: `File ${fileId} updated successfully` })
})
Functionality
  1. Endpoint Definition: The route handlers are set up to process URL-encoded form data for both creating and updating files.
  2. Request Handling:
    • Data Extraction: The parsed form data can be accessed either via req.body or the third parameter.
    • Processing: The code can access nested properties like file.title, file.description, etc.
  3. Response Handling: After processing the data, the server responds with appropriate status codes and messages.

multipart/form-data

Client-Side Code

<form action="/set-images" method="post" enctype="multipart/form-data">
    <input type="file" name="files" multiple />
    <button type="submit">Upload</button>
</form>

Description:

This HTML form allows users to upload multiple files to the server.

Server-Side Code

// POST example for uploading new files
app.post(
    "/set-images",
    async (req, res, data) => {
        const { files } = data
        try {
            for (const file of files) {
                const filePath = `images/${file.filename}`
                await writeFile(filePath, file.body)
            }
            res.redirect("/set/images")
        } catch (err) {
            console.error("Error writing files:", err)
            res.status(500).send("Internal Server Error")
        }
    },
    5 // 5MB limit
)

// PATCH example for updating existing files
app.patch(
    "/update-images/:folder",
    async (req, res) => {
        const folder = req.params.folder
        const { files } = req.body

        try {
            for (const file of files) {
                const filePath = `${folder}/${file.filename}`
                await writeFile(filePath, file.body)
            }
            res.json({ message: "Files updated successfully" })
        } catch (err) {
            console.error(`Error updating files in ${folder}:`, err)
            res.status(500).json({ error: "Failed to update files" })
        }
    },
    5 // 5MB limit
)

Description:

These server-side examples handle file uploads sent to different endpoints, showing both POST (create) and PATCH (update) operations.

meros

LiteNode internally uses the meros library to handle multipart/form-data submissions efficiently. meros is an extremely lightweight library, with a size of just 1KB, making it ideal for handling file uploads without adding significant overhead.

For each uploaded file, meros provides access to the following properties:

For more details about the meros library, you can visit its npm page.

Content