npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

micro-requester

v0.3.0

Published

Production-ready TypeScript package for standardized service-to-service HTTP calls in NestJS microservices

Readme

Micro Requester

Professional HTTP client for microservice-to-microservice communication in Node.js and NestJS projects.

npm version npm downloads License: MIT Node.js version TypeScript

Focused • Reliable • Small Surface Area • Production Ready


Why micro-requester?

micro-requester is intentionally focused on one job: reliable HTTP calls between services.

  • One primary API: createClient()
  • Preserves upstream 4xx payloads (like 409 Conflict) instead of masking them
  • Normalizes transport failures into predictable gateway-style errors
  • Built-in timeout and retry control with sensible defaults
  • Works in plain Node.js and NestJS

If your project has custom middleware, tracing, or request context strategy, keep that in your app and pass getReqId.


Installation

npm install micro-requester

Requirements: Node.js 18+


Quick Start

import { createClient } from 'micro-requester';

const users = createClient({
  service: 'users-service',
  base: process.env.USERS_SERVICE_HTTP_URL || 'http://localhost:3001',
  timeoutMs: 5000,
  retries: 2,
  getReqId: () => requestContext.getStore()?.requestId, // optional
});

const user = await users.get('/users/1');

const created = await users.post('/users', {
  email: '[email protected]',
  name: 'Alice',
});

API Reference

createClient(options)

Creates a reusable client for one upstream service.

type ClientOptions = {
  service: string;
  base: string;
  timeoutMs?: number;
  retries?: number;
  retryStatuses?: number[];
  headers?: Record<string, string>;
  getReqId?: () => string | undefined;
};

Parameter details:

  • service: service label used in mapped errors
  • base: upstream base URL
  • timeoutMs: default timeout per request (default 5000)
  • retries: default retry count (default 2)
  • retryStatuses: status codes considered retryable for idempotent methods (default [502, 503, 504])
  • headers: default headers merged into every request
  • getReqId: optional request ID resolver; falls back to generated UUID

Client

type Client = {
  req<T>(input: ReqInput): Promise<T>;
  get<T>(path: string, opts?: Partial<ReqInput>): Promise<T>;
  post<T>(path: string, body?: unknown, opts?: Partial<ReqInput>): Promise<T>;
  put<T>(path: string, body?: unknown, opts?: Partial<ReqInput>): Promise<T>;
  patch<T>(path: string, body?: unknown, opts?: Partial<ReqInput>): Promise<T>;
  delete<T>(path: string, opts?: Partial<ReqInput>): Promise<T>;
};

ReqInput

type ReqInput = {
  method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
  path: string;
  body?: unknown;
  query?: Record<string, string | number | boolean | undefined>;
  headers?: Record<string, string>;
  timeoutMs?: number;
  retry?: false | number;
};

Notes:

  • If body is an object, it is JSON-stringified automatically.
  • If content-type is missing for object body, application/json is set.
  • x-request-id is always attached to outgoing requests.
  • req() supports all methods in ReqInput, including HEAD and OPTIONS.

Error Behavior

Upstream responses

  • 4xx responses are passed through with original body/message
  • 5xx responses are normalized to 502 Bad Gateway

Transport failures

  • ECONNREFUSED -> 503 Service Unavailable
  • timeout/abort/UND_ERR* -> 504 Gateway Timeout
  • other transport failures -> 502 Bad Gateway

This behavior is designed to prevent business errors (for example duplicate email 409) from being hidden by generic transport messages.


Retry Model

Retries are conservative by default:

  • Retryable methods: GET, HEAD, OPTIONS
  • Retryable statuses: 502, 503, 504
  • Retryable transport errors: ECONNREFUSED, ETIMEDOUT, ENOTFOUND, UND_ERR_CONNECT_TIMEOUT, UND_ERR_SOCKET

Backoff:

  • Exponential: 100 * 2^attempt
  • Jitter: up to 50ms
  • Max delay: 1500ms

Override per request:

await users.get('/health', { retry: false });
await users.get('/health', { retry: 1 });

NestJS Integration Example

import { Injectable } from '@nestjs/common';
import { createClient } from 'micro-requester';
import { requestContext } from './request-context.middleware';

@Injectable()
export class UsersClient {
  private readonly client = createClient({
    service: 'users-service',
    base: process.env.USERS_SERVICE_HTTP_URL || 'http://localhost:3001',
    timeoutMs: 5000,
    retries: 2,
    getReqId: () => requestContext.getStore()?.requestId,
  });

  getUser(id: string) {
    return this.client.get(`/users/${id}`);
  }

  createUser(body: unknown) {
    return this.client.post('/users', body);
  }
}

Design Philosophy

  • Keep package concerns inside HTTP execution and error mapping
  • Keep project concerns (middleware/context/observability) inside your app
  • Preserve upstream business errors by default

License

MIT