Netpress Laravel-inspired backend framework for Node.js
Frameworkv0.1.14 Starterv0.1.12 Docsv1.0.3
Overview Installation Architecture CLI
Features

Requests and Validation

Request classes in NetPress work like Laravel form requests. They keep validation rules out of controllers and make route definitions cleaner.

Quick Example

// app/Http/Requests/Auth/RegisterRequest.js
import { body } from "express-validator";
import { BaseRequest } from "@admicaa/netpress";

export default class RegisterRequest extends BaseRequest {
  static rules() {
    return [
      body("name").trim().notEmpty().withMessage("Name is required"),
      body("email").trim().isEmail().withMessage("Invalid email address"),
      body("password").isLength({ min: 8 }).withMessage("Password is too short"),
    ];
  }
}

Use it inside the controller:

const payload = await this.validate(req, RegisterRequest);

Explanation

Each request class extends BaseRequest. You define rules(), and then you can use it in two ways:

  • await this.validate(req, RegisterRequest) inside a BaseController
  • RegisterRequest.middleware() at the route level

If validation fails, NetPress throws a ValidationException.

  • For API requests, the global handler returns JSON with status 422
  • For web forms, you can catch that error and redirect with withErrors() and withInput()

Additional Examples

Validate post creation:

import { body } from "express-validator";
import { BaseRequest } from "@admicaa/netpress";

export default class StorePostRequest extends BaseRequest {
  static rules() {
    return [
      body("title").trim().notEmpty().withMessage("Title is required"),
      body("slug").trim().notEmpty().withMessage("Slug is required"),
      body("body").trim().notEmpty().withMessage("Body is required"),
    ];
  }
}

Use it with auth:

router.post("/posts", authMiddleware, PostController.store);

Validation Flow For Forms

This is the usual flow for a server-rendered form:

  1. the user submits the form
  2. the controller runs this.validate()
  3. if validation fails, the controller redirects back
  4. the redirect flashes errors and old input
  5. the next page render reads errors and old()
// app/Http/Controllers/Auth/RegisterController.js
import {
  BaseController,
  ValidationException,
  redirect,
} from "@admicaa/netpress";
import RegisterRequest from "../../Requests/Auth/RegisterRequest.js";

class RegisterController extends BaseController {
  async store(req) {
    try {
      const payload = await this.validate(req, RegisterRequest);

      // Save the user here...

      return redirect("/dashboard");
    } catch (error) {
      if (error instanceof ValidationException) {
        return redirect("/register")
          .withErrors(error.errors)
          .withInput(req.body);
      }

      throw error;
    }
  }
}

The next request can read:

  • errors.has("email")
  • errors.first("email")
  • old("email")

Advanced Usage

Keep request classes focused on input rules. If you need database lookups, derived fields, or cross-model workflows, perform them in the controller or service after validation succeeds.

Notes / Tips

  • Keep one request class per action when the rules differ.
  • Reuse small validation helpers if several requests share the same fields.
  • Prefer clear error messages over clever validation chains.
  • this.validate(req, RequestClass) returns the validated payload and also stores it on req.validated.
  • withInput(req.body) is best for normal form input. Avoid flashing very large payloads.