DEV Community

Roman Onishchenko
Roman Onishchenko

Posted on

I got tired of rewriting the same HTTP client — so I built one

At some point, I noticed a pattern.

Almost every project I worked on had the same thing:

An HTTP client.

Not just a simple one — but something with:

  • retries
  • authentication
  • logging
  • error handling
  • timeouts
  • request lifecycle logic

And every time, it was slightly different.

Not better. Just different.


The problem

When services talk to each other, things get messy quickly.

Requests fail, timeouts happen, retries behave unpredictably, errors are inconsistent.

And instead of solving business problems, you end up rewriting infrastructure code.

Again and again.


What I wanted

I didn’t want another "just fetch wrapper".

I wanted something:

  • predictable
  • explicit
  • easy to reason about
  • flexible when needed

Especially for:

  • microservices
  • internal APIs
  • integration services
  • background jobs

So I built @dfsync/client

A lightweight HTTP client focused on reliable service-to-service communication in Node.js.

HTTP client for service-to-service communication

It’s part of an open-source toolkit:
👉 https://github.com/dfsyncjs/dfsync


Example

import { createClient } from '@dfsync/client';

const client = createClient({
  baseURL: 'https://api.service.local',
  retry: {
    attempts: 3,
    backoff: 'exponential',
    baseDelayMs: 300
  },
});

const response = await client.get('/users');
Enter fullscreen mode Exit fullscreen mode

What’s already there

  • retry support
  • auth handling
  • request lifecycle hooks: beforeRequest, afterResponse, onError
  • structured error handling

What I’m working on now (0.6.x)

Right now I’m focusing on request lifecycle improvements:

  • AbortSignal support
  • request context (passing metadata through lifecycle)
  • correlation ID propagation (x-request-id)
  • improved hook context

What’s next

Planned direction:

  • observability (latency, retry metadata)
  • safer integrations (validation, idempotency)

Why I’m sharing this

This is still early, and I’d really like feedback.

  • Does this solve a real problem for you?
  • What would you expect from such a client?
  • What’s missing?

Links

GitHub: https://github.com/dfsyncjs/dfsync
npm: https://www.npmjs.com/package/@dfsync/client
Website: https://dfsyncjs.github.io
LinkedIn: https://www.linkedin.com/company/dfsync

If you’ve ever rewritten the same HTTP client — I’d love to hear your experience.

Top comments (0)