Response objects with parsed bodies, metadata, timing information, and utilities for processing HTTP responses.
The main response interface containing parsed body data and comprehensive metadata.
/**
* Complete response object with parsed body and metadata
*/
interface Response<T = unknown> extends PlainResponse {
/**
* Parsed response body based on responseType
*/
body: T;
/**
* HTTP status code
*/
statusCode: number;
/**
* HTTP status message
*/
statusMessage?: string;
/**
* Response headers
*/
headers: IncomingHttpHeaders;
/**
* Original request URL
*/
requestUrl: URL;
/**
* Array of redirect URLs if redirects occurred
*/
redirectUrls: URL[];
/**
* Final URL after redirects
*/
url: string;
/**
* Request object that generated this response
*/
request: Request;
/**
* Detailed timing information
*/
timings: Timings;
/**
* Number of retry attempts made
*/
retryCount: number;
/**
* Whether response indicates success (2xx status)
*/
ok: boolean;
/**
* Whether response was retrieved from cache
*/
isFromCache: boolean;
/**
* Remote IP address (if available)
*/
ip?: string;
/**
* Raw response body buffer
*/
rawBody?: Buffer;
}The base response interface without parsed body, used internally and for error handling.
/**
* Response object without parsed body
*/
interface PlainResponse {
/**
* Original request URL
*/
requestUrl: URL;
/**
* Array of redirect URLs
*/
redirectUrls: URL[];
/**
* Request object that generated this response
*/
request: Request;
/**
* Remote IP address (if available)
*/
ip?: string;
/**
* Whether response was retrieved from cache
*/
isFromCache: boolean;
/**
* HTTP status code
*/
statusCode: number;
/**
* Final URL after redirects
*/
url: string;
/**
* Detailed timing information
*/
timings: Timings;
/**
* Number of retry attempts made
*/
retryCount: number;
/**
* Raw response body buffer (if available)
*/
rawBody?: Buffer;
/**
* Parsed response body (if available)
*/
body?: unknown;
/**
* Whether response indicates success
*/
ok: boolean;
}Response body parsing based on the responseType option and content type detection.
/**
* Parse response body based on response type
* @param response - Raw response object
* @param responseType - Desired response type
* @param parseJson - Custom JSON parsing function
* @param encoding - Text encoding for string responses
* @returns Parsed response body
*/
function parseBody<T>(
response: IncomingMessageWithTimings,
responseType: ResponseType,
parseJson?: ParseJsonFunction,
encoding?: BufferEncoding
): T;
/**
* Response body parsing types
*/
type ResponseType = "text" | "json" | "buffer";
/**
* Custom JSON parsing function
*/
type ParseJsonFunction = (text: string) => unknown;Usage Examples:
import got from "got";
// Text response
const textResponse = await got("https://example.com", {
responseType: "text"
});
console.log(typeof textResponse.body); // "string"
// JSON response
const jsonResponse = await got("https://api.example.com/users", {
responseType: "json"
});
console.log(typeof jsonResponse.body); // "object"
// Buffer response
const bufferResponse = await got("https://example.com/image.png", {
responseType: "buffer"
});
console.log(Buffer.isBuffer(bufferResponse.body)); // true
// Custom JSON parsing
const customResponse = await got("https://api.example.com/data", {
responseType: "json",
parseJson: (text) => {
return JSON.parse(text, (key, value) => {
// Convert ISO date strings to Date objects
if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(value)) {
return new Date(value);
}
return value;
});
}
});Detailed timing information for performance monitoring and debugging.
/**
* Detailed timing information for HTTP requests
*/
interface Timings {
/**
* Time when the request started
*/
start: number;
/**
* Time when a socket was assigned
*/
socket?: number;
/**
* Time when DNS lookup finished
*/
lookup?: number;
/**
* Time when socket connected
*/
connect?: number;
/**
* Time when TLS handshake completed
*/
secureConnect?: number;
/**
* Time when request was sent
*/
upload?: number;
/**
* Time when response started
*/
response?: number;
/**
* Time when response finished
*/
end?: number;
/**
* Time when error occurred
*/
error?: number;
/**
* Time when request was aborted
*/
abort?: number;
/**
* Calculated phase timings
*/
phases: {
/**
* Time waiting for socket assignment
*/
wait?: number;
/**
* DNS lookup time
*/
dns?: number;
/**
* TCP connection time
*/
tcp?: number;
/**
* TLS handshake time
*/
tls?: number;
/**
* Request upload time
*/
request?: number;
/**
* Time to first byte
*/
firstByte?: number;
/**
* Response download time
*/
download?: number;
/**
* Total request time
*/
total?: number;
};
}Usage Examples:
import got from "got";
const response = await got("https://api.example.com/data");
console.log("Timing breakdown:");
console.log(`DNS lookup: ${response.timings.phases.dns}ms`);
console.log(`TCP connect: ${response.timings.phases.tcp}ms`);
console.log(`TLS handshake: ${response.timings.phases.tls}ms`);
console.log(`Request: ${response.timings.phases.request}ms`);
console.log(`First byte: ${response.timings.phases.firstByte}ms`);
console.log(`Download: ${response.timings.phases.download}ms`);
console.log(`Total: ${response.timings.phases.total}ms`);
// Performance monitoring
if (response.timings.phases.total > 5000) {
console.warn("Slow request detected:", response.requestUrl.href);
}Utilities for checking response status and success conditions.
/**
* Check if response status indicates success
* @param response - Response object
* @returns Whether response is successful
*/
function isResponseOk(response: PlainResponse): boolean;Usage Examples:
import got from "got";
// Disable automatic error throwing
const response = await got("https://api.example.com/might-fail", {
throwHttpErrors: false
});
// Manual status checking
if (response.ok) {
console.log("Request successful:", response.body);
} else {
console.error(`Request failed: ${response.statusCode} ${response.statusMessage}`);
// Handle specific status codes
switch (response.statusCode) {
case 404:
console.log("Resource not found");
break;
case 429:
console.log("Rate limited");
break;
case 500:
console.log("Server error");
break;
default:
console.log("Other error:", response.statusCode);
}
}
// Check response properties
console.log("Status:", response.statusCode);
console.log("Headers:", response.headers);
console.log("From cache:", response.isFromCache);
console.log("Redirects:", response.redirectUrls.length);
console.log("Retries:", response.retryCount);Working with HTTP response headers and metadata.
/**
* HTTP response headers
*/
type IncomingHttpHeaders = Record<string, string | string[] | undefined>;Usage Examples:
import got from "got";
const response = await got("https://api.example.com/data");
// Access common headers
console.log("Content-Type:", response.headers["content-type"]);
console.log("Content-Length:", response.headers["content-length"]);
console.log("Cache-Control:", response.headers["cache-control"]);
console.log("ETag:", response.headers.etag);
// Check for specific headers
if (response.headers["x-ratelimit-remaining"]) {
const remaining = parseInt(response.headers["x-ratelimit-remaining"] as string);
if (remaining < 10) {
console.warn("Rate limit nearly exceeded:", remaining);
}
}
// Link header parsing for pagination
if (response.headers.link) {
const linkHeader = response.headers.link as string;
console.log("Link header:", linkHeader);
// Parse link header (requires parseLinkHeader utility)
const links = parseLinkHeader(linkHeader);
console.log("Next page:", links.next);
}
// Last-Modified header for caching
if (response.headers["last-modified"]) {
const lastModified = new Date(response.headers["last-modified"] as string);
console.log("Last modified:", lastModified);
}Convenient methods for accessing different response types without specifying responseType.
interface CancelableRequest<T> extends Promise<T> {
/**
* Get response body as parsed JSON
* @returns Promise resolving to parsed JSON
*/
json<ReturnType>(): CancelableRequest<ReturnType>;
/**
* Get response body as Buffer
* @returns Promise resolving to Buffer
*/
buffer(): CancelableRequest<Buffer>;
/**
* Get response body as text string
* @returns Promise resolving to string
*/
text(): CancelableRequest<string>;
}Usage Examples:
import got from "got";
// JSON shortcut
const users = await got("https://api.example.com/users").json();
console.log(users); // Parsed JSON object
// Text shortcut
const html = await got("https://example.com").text();
console.log(typeof html); // "string"
// Buffer shortcut
const imageBuffer = await got("https://example.com/image.png").buffer();
console.log(Buffer.isBuffer(imageBuffer)); // true
// Type-safe JSON shortcut
interface User {
id: number;
name: string;
email: string;
}
const typedUsers = await got("https://api.example.com/users").json<User[]>();
console.log(typedUsers[0].name); // TypeScript knows this is a stringInformation about cached responses and cache behavior.
import got from "got";
const response = await got("https://api.example.com/data", {
cache: true
});
// Check if response came from cache
if (response.isFromCache) {
console.log("Response served from cache");
} else {
console.log("Fresh response from server");
}
// Cache-related headers
console.log("Cache-Control:", response.headers["cache-control"]);
console.log("ETag:", response.headers.etag);
console.log("Expires:", response.headers.expires);
// Conditional requests
const etag = response.headers.etag;
if (etag) {
const conditionalResponse = await got("https://api.example.com/data", {
headers: {
"If-None-Match": etag
},
throwHttpErrors: false
});
if (conditionalResponse.statusCode === 304) {
console.log("Content not modified, use cached version");
}
}Working with streaming responses for large data or real-time processing.
import got from "got";
import { pipeline } from "node:stream";
import { createWriteStream } from "node:fs";
// Stream large responses
const downloadStream = got.stream("https://example.com/large-file.zip");
downloadStream.on("response", (response) => {
console.log("Response started:");
console.log("Status:", response.statusCode);
console.log("Content-Length:", response.headers["content-length"]);
console.log("Content-Type:", response.headers["content-type"]);
});
downloadStream.on("downloadProgress", (progress) => {
if (progress.total) {
const percent = Math.round((progress.transferred / progress.total) * 100);
console.log(`Download progress: ${percent}%`);
}
});
// Save to file
await pipeline(downloadStream, createWriteStream("download.zip"));Handling different response scenarios and error conditions.
import got, { HTTPError } from "got";
async function handleResponse() {
try {
const response = await got("https://api.example.com/data");
// Successful response
console.log("Success:", response.statusCode);
return response.body;
} catch (error) {
if (error instanceof HTTPError) {
// HTTP error response
const { response } = error;
console.log("HTTP Error:", response.statusCode);
console.log("Response body:", response.body);
console.log("Headers:", response.headers);
// Handle specific errors
if (response.statusCode === 429) {
const retryAfter = response.headers["retry-after"];
console.log("Rate limited, retry after:", retryAfter);
}
return null;
} else {
// Network or other error
throw error;
}
}
}
// Graceful handling without throwing
async function safeRequest() {
const response = await got("https://api.example.com/data", {
throwHttpErrors: false
});
return {
success: response.ok,
status: response.statusCode,
data: response.ok ? response.body : null,
error: response.ok ? null : response.statusMessage
};
}