Requests
ExisJS wraps the native Node.js IncomingMessage object into a highly optimized, developer-friendly ExisRequest instance. It abstracts away the complexities of stream parsing, multipart form processing, and header normalization, giving you an ultra-fast and fully typed interface.
1. Body, Query, and Params
The most common request properties are automatically parsed and strongly typed (especially when using the Schema Validation middleware).
req.body: The parsed body of the request (JSON, URL-encoded, or Multipart).req.query: An object containing the URL query string parameters (e.g.,?id=123).req.params: An object containing route parameters (e.g.,/:id).
Functional Paradigm
export default controller({ updateUser: route.post('/users/:id', { handle(req, res) { const id = req.params.id // "123" const force = req.query.force // "true" const payload = req.body // { email: "alice@exisjs.com" } } })})Class-Based (OOP) Paradigm
import { Controller, Post, Param, Query, Body } from 'exisjs/decorators'
@Controller()export default class UsersController { @Post('/users/:id') async updateUser( @Param('id') id: string, @Query('force') force: string, @Body() payload: any ) { // Variables are automatically injected! }}2. On-Demand Parsing
To maximize performance, ExisJS does not parse the request body immediately for every route. If you aren't using the Validation middleware, you can manually trigger parsing on-demand.
Functional Paradigm
export default controller({ processData: route.post('/process', { async handle(req, res) { // Parses application/json const data = await req.json<{ key: string }>() // Parses raw text (text/plain) const text = await req.text() } })})Class-Based (OOP) Paradigm
import { Controller, Post, Req } from 'exisjs/decorators'
@Controller()export default class ProcessController { @Post('/process') async processData(@Req() req: any) { // Parses application/json const data = await req.json<{ key: string }>() // Parses raw text (text/plain) const text = await req.text() }}3. File Uploads & Form Data
Handling multipart/form-data in Node.js is traditionally a nightmare. ExisJS provides a native, highly secure stream parser out-of-the-box.
Calling req.formData() returns both the standard text fields and the uploaded files. ExisJS also attaches a highly convenient .saveToDisk() helper to every uploaded file, which automatically handles writing the buffer and generating collision-free filenames!
Functional Paradigm
import { controller, route } from 'exisjs/router'
export default controller({ uploadAvatar: route.post('/avatar', { async handle(req, res) { // 1. Parse the multipart form data const { fields, files } = await req.formData() // 2. Access the file (e.g., from an input named "profile_pic") const uploadedFile = files['profile_pic'] if (uploadedFile) { // 3. Save it to disk safely! Returns the absolute saved path. const savedPath = await uploadedFile.saveToDisk('./uploads/avatars') return { success: true, path: savedPath } } return { success: false, error: "No file uploaded" } } })})Class-Based (OOP) Paradigm
import { Controller, Post, UploadedFile } from 'exisjs/decorators'
@Controller()export default class UploadController { @Post('/avatar') async uploadAvatar(@UploadedFile('profile_pic') profilePic: any) { if (profilePic) { // Save it to disk safely! Returns the absolute saved path. const savedPath = await profilePic.saveToDisk('./uploads/avatars') return { success: true, path: savedPath } } return { success: false, error: "No file uploaded" } }}4. HTTP Headers & Content Negotiation
// Get a specific header (case-insensitive)const authHeader = req.get('Authorization')// orconst authHeader = req.header('authorization')
// Check the Content-Typeif (req.is('application/json')) { ... }
// Content Negotiation (returns the best match)const format = req.accepts('html', 'json', 'text')const language = req.acceptsLanguages('en', 'es', 'fr')5. Network Information
ExisJS handles trust-proxies gracefully. If you are behind Cloudflare, Nginx, or an AWS Load Balancer, simply set trustProxy: true in your exis() config, and these properties will automatically resolve the true client IP from X-Forwarded-For.
req.ip: The client's IP address.req.ips: An array of IPs if multiple proxies were traversed.req.hostname: The resolved hostname (fromHostorX-Forwarded-Host).req.protocol: Returns'http'or'https'.req.secure: A boolean (true ifreq.protocol === 'https').
6. Context & Metadata
As your request moves through ExisJS Middlewares, various properties are attached to req for your convenience:
req.log: A request-scoped instance of the Pino logger (viarequestLogger).req.requestId: The unique Trace ID (viarequestId).req.user: The authenticated user payload (viaJWTauth middleware).req.session: The stateful session object (viasessionmiddleware).req.fresh: Returnstrueif the client's cache is still valid (ETag match), meaning you can send a 304 response.