v0.21

requests

introduction

the Request class wraps the raw node http request to provide an api for interacting with incoming data. it parses the url, query strings, headers, and body payloads (json, form urlencoded, and multipart files).

in controllers and middleware, the request instance is injected as the req argument.

the request context

the framework utilizes AsyncLocalStorage to maintain request state across the entire asynchronous call stack. this allows you to access the current request globally without passing the req object down through every function.

1import { RequestContext } from 'dframework';
2
3function getClientIp() {
4 const req = RequestContext.get();
5 return req ? req.headers['x-forwarded-for'] || req.socket.remoteAddress : null;
6}

request identity

the request object provides several getters to determine the origin and format of the request.

1// returns true if the request comes from native builds
2if (req.isNative) {
3 return json({ success: true, native: true });
4}
5
6// returns true for XMLHttpRequest, dSPAHttpRequest, or application/json accept headers
7if (req.isAjax) {
8 return abort(422, 'validation failed');
9}
10
11// returns client ip address (honors X-Forwarded-For / X-Real-IP when app.trustProxy is enabled)
12const clientIp = req.ip;
13
14// returns true specifically for the framework's client side spa router
15if (req.isSPA) {
16 return json({ component: 'Home' });
17}

input and parameters

the framework lazily parses input to avoid overhead on routes that don't need it.

1// parsed from the query string (e.g. ?search=term)
2const query = req.query.search;
3
4// parsed from the cookie header
5const locale = req.cookies.locale;
6
7// automatically extracts and ensures 'page' is an integer, defaulting to 1
8const page = req.page;
9
10// retrieve unified input across params, body, and query (priority: params > body > query)
11const name = req.input('name', 'guest');
12const role = req.input('role');
13
14// retrieve all merged inputs
15const allInputs = req.all(); // or req.input()
16
17// retrieve uploaded file instance (first item if array)
18const avatar = req.file('avatar');
19
20// check if a file was uploaded for the given key
21if (req.hasFile('document')) {
22 const doc = req.file('document');
23}

as detailed in the controllers documentation, req.body and req.files are populated automatically for mutating requests (POST, PUT, PATCH, DELETE) by the route compiler. you can also use req.file(key) to retrieve the first file directly, or req.hasFile(key) to verify that an uploaded file is present.

streaming requests

to consume or pipe the raw incoming request payload directly without accumulating chunks in memory, you can obtain a readable stream:

1const stream = req.createReadableStream();
2if (stream) {
3 for await (const chunk of stream) {
4 // process chunk
5 }
6}

headers

you can retrieve headers using the header() method, which is case insensitive.

1const userAgent = req.header('user-agent');
2const referer = req.header('referrer'); // handles both referer and referrer

csrf management

the request object handles generating and verifying csrf tokens.

NOTE

the route compiler automatically inserts verification logic for all mutating routes (`POST`, `PUT`, `PATCH`, `DELETE`) unless explicitly disabled, so you rarely call these methods manually.

1// generate a new token valid for 6 hours
2const token = req.csrfToken();
3
4// verify a submitted token
5const isValid = req.verifyCsrfToken(submittedToken);
6
7// rotate the csrf secret and generate a fresh token (invalidates previous tokens)
8const newToken = req.rotateCsrfToken();