In-Process HTTP Request Executor
raw JSON →in-process-request is a lightweight Node.js library designed to execute HTTP handler functions directly within the current process, bypassing the need to start and manage a local HTTP server. This makes it ideal for integration testing of API routes or for internal service-to-service communication within the same application without network overhead. The library provides a unified interface for interacting with handlers from popular web frameworks including Express.js (v3, v4, v5), Koa (v2), Hapi (v19, v20), NestJS (v7), Fastify (v3), Connect (v3), Polka, and Apollo Server (v2, v3). Its current stable version is 0.3.1, with releases typically focusing on bug fixes, dependency updates, and ensuring compatibility with newer versions of supported frameworks. It differentiates itself by offering a robust mocking layer for HTTP requests and responses, allowing for precise control over the input and examination of the output.
Common errors
error Error: The 'path' property is mandatory in requestOptions. ↓
requestOptions includes a non-empty path string, e.g., handler({ path: '/api/resource', method: 'GET' }). error TypeError: app.callback is not a function ↓
koaApp.callback() to inProcessRequest, not koaApp. Correct usage: const handler = inProcessRequest(koaApp.callback()); error TypeError: listener is not an instance of Server ↓
HapiListener helper class. Create an instance of HapiListener, pass it to Hapi.server({ listener: myListener }), and then use myListener.handler with inProcessRequest. Example: const myListener = new HapiListener(); const server = Hapi.server({ listener: myListener }); const handler = inProcessRequest(myListener.handler); Warnings
gotcha Ensure the target web framework version is explicitly supported by `in-process-request`. While the library aims for broad compatibility, changes in framework internals can lead to unexpected behavior or require updates. Refer to the package's README for the list of officially tested and supported framework versions. ↓
gotcha The `requestOptions.path` property is mandatory for every request. Omitting or providing an empty string for `path` will result in an error, as the library cannot determine which route to match. ↓
gotcha The request and response objects provided to and returned from the handler are mocks, not actual `http.IncomingMessage` and `http.ServerResponse` instances. While they replicate essential properties and methods, deep reliance on specific Node.js HTTP stream or socket properties that are not explicitly mocked may lead to issues. ↓
Install
npm install in-process-request yarn add in-process-request pnpm add in-process-request Imports
- inProcessRequest wrong
const inProcessRequest = require('in-process-request');correctimport inProcessRequest from 'in-process-request'; - HapiListener wrong
const { HapiListener } = require('in-process-request'); const HapiListener = require('in-process-request').HapiListener;correctimport { HapiListener } from 'in-process-request'; - InProcessRequestHandler
import inProcessRequest, { InProcessRequestHandler } from 'in-process-request'; let handler: InProcessRequestHandler;
Quickstart
import inProcessRequest from 'in-process-request';
import express from 'express';
// Create a basic Express application
const myApp = express();
myApp.use(express.json()); // Enable JSON body parsing
myApp.get('/api/test', (req, res) => {
res.json({ message: 'Hello from API!', query: req.query });
});
myApp.post('/api/data', (req, res) => {
if (!req.body || Object.keys(req.body).length === 0) {
return res.status(400).json({ error: 'Request body is empty' });
}
res.status(201).json({ received: req.body, timestamp: new Date().toISOString() });
});
// Create an in-process handler for the Express app
const myAppHandler = inProcessRequest(myApp);
async function runTests() {
// Test a GET request
const getResponse = await myAppHandler({
path: '/api/test?param1=value1¶m2=value2',
method: 'GET',
headers: { 'Accept': 'application/json' }
});
console.log('--- GET Request Result ---');
console.log('Status Code:', getResponse.statusCode);
if (getResponse.isUTF8) {
const body = getResponse.body.toString('utf8');
console.log('Body:', body);
console.log('Parsed JSON:', JSON.parse(body));
}
// Test a POST request with a JSON body
const postResponse = await myAppHandler({
path: '/api/data',
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ item: 'sample', quantity: 10 })
});
console.log('\n--- POST Request Result ---');
console.log('Status Code:', postResponse.statusCode);
if (postResponse.isUTF8) {
const body = postResponse.body.toString('utf8');
console.log('Body:', body);
console.log('Parsed JSON:', JSON.parse(body));
}
}
runTests();