http-call
http-call is a lightweight, promise-based HTTP client designed for making RESTful API requests. Maintained by Heroku, it provides a fluent interface for common HTTP methods (GET, POST, PUT, DELETE) and simplifies interaction with JSON APIs by automatically converting responses. The current stable version is 5.5.1, with a release cadence that includes regular bug fixes and minor feature enhancements. Key differentiators include built-in TypeScript support, automatic JSON parsing, and a focus on clean, asynchronous API consumption, making it suitable for modern Node.js applications that require robust HTTP communication without extensive configuration. It is widely used within the Heroku ecosystem for interacting with platform services.
Common errors
-
Error [ERR_REQUIRE_ESM]: require() of ES Module /path/to/node_modules/http-call/dist/index.js not supported.
cause Attempting to use `require()` to load `http-call` in an environment where it's treated as an ES Module, typically in a CommonJS context.fixIf your project is ES Module-based, use `import { HTTP } from 'http-call'`. If your project is CommonJS, ensure your bundler/TypeScript configuration is correctly set up to consume dual-package formats, or ensure you are on a Node.js version that properly handles CJS-importing-ESM interop (typically Node.js 12.20+ or 14.13+ with `--experimental-json-modules` flag, though general CJS `require` of ESM is still a hard error without dynamic `import()`). The most reliable fix is to migrate to ESM if possible or use dynamic imports. -
TypeError: HTTP.get is not a function
cause This usually indicates incorrect destructuring of the import or attempting to call a method on an undefined or improperly imported object.fixEnsure you are correctly destructuring `HTTP` from the module: `import { HTTP } from 'http-call'` or `const { HTTP } = require('http-call')`. If it's still failing, check if another package named `http-call` is accidentally being imported or if the installation is corrupted. -
TS2345: Argument of type 'string' is not assignable to parameter of type 'number | undefined'.
cause When using TypeScript, providing a non-numeric value to the `timeout` option (or other configuration options expecting specific types) will cause a type error.fixEnsure all options passed to `HTTP` methods or the configuration object conform to the expected TypeScript types. For `timeout`, provide a `number` representing milliseconds or `0` for no timeout: `await HTTP.get(url, { timeout: 5000 })`.
Warnings
- gotcha Starting with v5.4.0, `http-call` introduced a default timeout for requests. Previously, requests might have waited indefinitely. This change can affect applications that relied on long-running or unbounded HTTP requests, potentially causing unexpected timeouts.
- gotcha While `http-call` supports both CommonJS (`require`) and ES Modules (`import`), mixing them incorrectly in a single project can lead to `ERR_REQUIRE_ESM` errors. Node.js's module resolution for interop can be complex.
- gotcha The library primarily operates on `Promise`s. While this is standard for modern JavaScript, improperly handling asynchronous operations (e.g., forgetting `await` or `.catch()`) can lead to unhandled promise rejections or incorrect control flow, especially when integrating with older callback-based code.
Install
-
npm install http-call -
yarn add http-call -
pnpm add http-call
Imports
- HTTP
const { HTTP } = require('http-call')import { HTTP } from 'http-call' - HTTP (CommonJS)
import { HTTP } from 'http-call'const { HTTP } = require('http-call') - HTTP (TypeScript with generics)
import { HTTP } from 'http-call'; // Incorrect: Type not specified const { body: user } = await HTTP.get('/users/me')import { HTTP } from 'http-call'; interface User { id: string; email: string; name: string; }
Quickstart
import { HTTP } from 'http-call';
interface GitHubUser {
login: string;
id: number;
node_id: string;
avatar_url: string;
name: string;
email: string | null;
bio: string | null;
}
async function getGitHubUser(username: string): Promise<GitHubUser> {
try {
const token = process.env.GITHUB_TOKEN ?? ''; // Use environment variable for auth
if (!token) {
console.warn('GITHUB_TOKEN environment variable is not set. Requests may be unauthenticated or rate-limited.');
}
const { body: user } = await HTTP.get<GitHubUser>(`https://api.github.com/users/${username}`, {
headers: { authorization: token ? `token ${token}` : '' }
});
console.log(`Successfully fetched user ${user.name || user.login}. ID: ${user.id}, Bio: ${user.bio || 'N/A'}`);
return user;
} catch (error: any) {
console.error(`Error fetching GitHub user ${username}:`, error.message);
throw error;
}
}
// Example usage:
(async () => {
try {
const myUser = await getGitHubUser('octocat');
console.log('GitHub User Details:', myUser);
} catch (e) {
// Error handled in getGitHubUser
}
try {
// Example with a non-existent user to demonstrate error handling
await getGitHubUser('nonexistentuser12345');
} catch (e) {
// Expected error, already logged
}
})();