A light-weight module that brings Fetch API to Node.js
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Classes for creating and manipulating HTTP requests and responses with full Body interface support, providing complete control over HTTP communication.
Represents an HTTP request with all necessary metadata and body content.
/**
* HTTP Request class implementing the Body interface
*/
class Request {
constructor(input: string | URL | Request, init?: RequestInit);
// Properties (read-only)
readonly method: string;
readonly url: string;
readonly headers: Headers;
readonly redirect: 'follow' | 'error' | 'manual';
readonly signal: AbortSignal;
readonly referrer: string;
readonly referrerPolicy: string;
// Node.js extensions
readonly follow: number;
readonly compress: boolean;
readonly counter: number;
readonly agent: http.Agent | ((parsedUrl: URL) => http.Agent);
readonly highWaterMark: number;
readonly insecureHTTPParser: boolean;
// Methods
clone(): Request;
// Body interface methods
readonly body: ReadableStream | null;
readonly bodyUsed: boolean;
arrayBuffer(): Promise<ArrayBuffer>;
blob(): Promise<Blob>;
formData(): Promise<FormData>;
json(): Promise<any>;
text(): Promise<string>;
}Usage Examples:
import { Request } from 'node-fetch';
// Create request from URL
const request = new Request('https://api.github.com/users/octocat');
// Create request with options
const postRequest = new Request('https://httpbin.org/post', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'Alice' })
});
// Clone request for reuse
const clonedRequest = postRequest.clone();
// Access request properties
console.log(request.url); // 'https://api.github.com/users/octocat'
console.log(request.method); // 'GET'
console.log(request.headers); // Headers object
// Use with fetch
const response = await fetch(request);Represents an HTTP response with status information, headers, and body content.
/**
* HTTP Response class implementing the Body interface
*/
class Response {
constructor(body?: BodyInit | null, init?: ResponseInit);
// Properties (read-only)
readonly status: number;
readonly statusText: string;
readonly ok: boolean;
readonly redirected: boolean;
readonly type: 'basic' | 'cors' | 'default' | 'error' | 'opaque' | 'opaqueredirect';
readonly url: string;
readonly headers: Headers;
// Methods
clone(): Response;
// Static methods
static redirect(url: string, status?: number): Response;
static error(): Response;
static json(data: any, init?: ResponseInit): Response;
// Body interface methods
readonly body: ReadableStream | null;
readonly bodyUsed: boolean;
arrayBuffer(): Promise<ArrayBuffer>;
blob(): Promise<Blob>;
formData(): Promise<FormData>;
json(): Promise<any>;
text(): Promise<string>;
}Usage Examples:
import fetch, { Response } from 'node-fetch';
// Standard fetch response
const response = await fetch('https://api.github.com/users/octocat');
// Check response status
if (response.ok) {
console.log('Success:', response.status);
} else {
console.error('Error:', response.status, response.statusText);
}
// Clone response for multiple reads
const clonedResponse = response.clone();
const text = await response.text();
const json = await clonedResponse.json();
// Create custom responses
const jsonResponse = Response.json({ message: 'Hello World' });
const redirectResponse = Response.redirect('https://example.com', 302);
const errorResponse = Response.error();Configuration object for creating custom Response instances.
interface ResponseInit {
status?: number;
statusText?: string;
headers?: HeadersInit;
}Usage Examples:
// Custom response with specific status
const customResponse = new Response('Custom content', {
status: 201,
statusText: 'Created',
headers: {
'Content-Type': 'text/plain',
'X-Custom-Header': 'value'
}
});
// JSON response with custom headers
const apiResponse = Response.json(
{ data: 'example', timestamp: Date.now() },
{
status: 200,
headers: {
'Cache-Control': 'no-cache',
'X-API-Version': '1.0'
}
}
);Both Request and Response classes implement the Body interface for consistent body processing.
interface Body {
readonly body: ReadableStream | null;
readonly bodyUsed: boolean;
arrayBuffer(): Promise<ArrayBuffer>;
blob(): Promise<Blob>;
formData(): Promise<FormData>;
json(): Promise<any>;
text(): Promise<string>;
}Usage Examples:
// Reading response body as different formats
const response = await fetch('https://api.github.com/users/octocat');
// As JSON (most common)
const userData = await response.json();
// As text
const htmlResponse = await fetch('https://example.com');
const htmlText = await htmlResponse.text();
// As ArrayBuffer for binary data
const imageResponse = await fetch('https://example.com/image.png');
const imageBuffer = await imageResponse.arrayBuffer();
// As Blob
const blob = await imageResponse.blob();
// Check if body has been consumed
console.log(response.bodyUsed); // true after calling json()Convenient properties for checking response success and handling errors.
interface ResponseStatus {
readonly status: number; // HTTP status code (200, 404, etc.)
readonly statusText: string; // HTTP status message ('OK', 'Not Found', etc.)
readonly ok: boolean; // true for 200-299 status codes
readonly redirected: boolean; // true if response was redirected
}Usage Examples:
const response = await fetch('https://api.example.com/data');
// Check success status
if (response.ok) {
const data = await response.json();
console.log('Success:', data);
} else {
console.error(`HTTP Error: ${response.status} ${response.statusText}`);
}
// Handle specific status codes
switch (response.status) {
case 200:
console.log('Success');
break;
case 404:
console.log('Resource not found');
break;
case 500:
console.log('Server error');
break;
default:
console.log(`Unexpected status: ${response.status}`);
}
// Check if response was redirected
if (response.redirected) {
console.log('Final URL:', response.url);
}Create copies of Request or Response objects for reuse or multiple processing.
interface Cloneable {
clone(): this;
}Usage Examples:
// Clone request for retry logic
const originalRequest = new Request('https://api.example.com/data', {
method: 'POST',
body: JSON.stringify({ data: 'important' })
});
async function fetchWithRetry(request, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const clonedRequest = request.clone();
return await fetch(clonedRequest);
} catch (error) {
if (attempt === maxRetries) throw error;
console.log(`Retry ${attempt} failed, trying again...`);
}
}
}
// Clone response for multiple processing
const response = await fetch('https://api.example.com/data');
const response1 = response.clone();
const response2 = response.clone();
// Process same response data in different ways
const json = await response1.json();
const text = await response2.text();Utility methods for creating common response types.
class Response {
/**
* Create a redirect response
* @param url - Redirect target URL
* @param status - HTTP redirect status code (default: 302)
*/
static redirect(url: string, status?: number): Response;
/**
* Create an error response
*/
static error(): Response;
/**
* Create a JSON response with automatic Content-Type header
* @param data - Data to serialize as JSON
* @param init - Additional response configuration
*/
static json(data: any, init?: ResponseInit): Response;
}Usage Examples:
// Create redirect responses
const tempRedirect = Response.redirect('https://new-location.com');
const permRedirect = Response.redirect('https://new-location.com', 301);
// Create error response
const errorResponse = Response.error();
console.log(errorResponse.status); // 0
console.log(errorResponse.ok); // false
// Create JSON responses
const apiResponse = Response.json({
status: 'success',
data: { id: 123, name: 'Example' },
timestamp: new Date().toISOString()
});
console.log(apiResponse.headers.get('Content-Type')); // 'application/json'