Skip to main content

wrapRouteHandler()

Type: Method on ExpressAdapter Access: nauth.adapter.wrapRouteHandler(handler)

Wraps a route handler with NAuthRequest/NAuthResponse interfaces, automatic error propagation, and optional response serialization. Unlike Fastify, Express middleware runs in a continuous call stack so AsyncLocalStorage context is preserved automatically --- this wrapper provides convenience, not context restoration.

Signature

wrapRouteHandler<T>(handler: NAuthRouteHandler<T>): ExpressMiddleware

Parameters

ParameterTypeDescription
handlerNAuthRouteHandler<T>(req: NAuthRequest, res: NAuthResponse) => Promise<T | void>

Returns

Standard Express middleware ((req, res, next) => void).

Usage

Basic Route

import { NAuth, ExpressAdapter } from '@nauth-toolkit/core';

const nauth = await NAuth.create({
config: authConfig,
dataSource,
adapter: new ExpressAdapter(),
});

app.post('/auth/login',
nauth.helpers.public(),
nauth.adapter.wrapRouteHandler(async (req, res) => {
res.json(await nauth.authService.login(req.body));
}),
);

Return Value Auto-Serialization

If your handler returns a value and the response hasn't been sent, the wrapper automatically calls res.json():

app.get('/auth/profile',
nauth.helpers.requireAuth(),
nauth.adapter.wrapRouteHandler(async () => {
// Returned value is automatically sent as JSON
return nauth.helpers.getCurrentUser();
}),
);

With Status Codes

app.post('/auth/signup',
nauth.helpers.public(),
nauth.adapter.wrapRouteHandler(async (req, res) => {
res.status(201).json(await nauth.authService.signup(req.body));
}),
);

Behavior

  1. Ensures request attributes are initialized
  2. Wraps express.Request and express.Response into NAuthRequest and NAuthResponse
  3. Executes your handler inside a try/catch block
  4. If the handler returns a value and res.headersSent is false, sends the value as JSON
  5. If the handler throws, passes the error to next() for Express error handling

When to Use

wrapRouteHandler() is optional for Express (unlike Fastify where it's required). Use it when you want:

  • NAuthRequest/NAuthResponse interfaces instead of raw Express types
  • Automatic error forwarding to Express error handlers via next(error)
  • Return-value auto-serialization

For simple routes, you can call nauth services directly without the wrapper:

app.post('/auth/login', nauth.helpers.public(), async (req, res, next) => {
try {
res.json(await nauth.authService.login(req.body));
} catch (err) { next(err); }
});