@kudoengineer/http
v1.0.0
Published
Modern, lightweight and production-ready HTTP client library for Angular with base URL configuration, authentication, retry, timeout, cancellation, caching, request deduplication, request IDs, logging and reactive Signals support.
Maintainers
Keywords
Readme
@kudoengineer/http
Modern, lightweight and production-ready HTTP client library for Angular.
@kudoengineer/http provides a clean and powerful API on top of Angular HttpClient, with built-in support for authentication, retry policies, timeout, cancellation, caching, request deduplication, request IDs, logging and Angular Signals.
Built for modern Angular applications and scalable enterprise projects.
✨ Features
- ✅ Angular Standalone support
- ✅ TypeScript support
- ✅ GET, POST, PUT, PATCH, DELETE, HEAD and OPTIONS
- ✅ Base URL configuration
- ✅ Global headers
- ✅ Request-specific headers
- ✅ Query parameters
- ✅ Authentication / Token Provider
- ✅ JWT / Bearer token support
- ✅ URL include/exclude authentication rules
- ✅ Automatic error normalization
- ✅ Retry with exponential backoff
- ✅ Configurable retry status codes
- ✅ Request timeout
- ✅ Request cancellation with
AbortSignal - ✅ Request ID generation
- ✅ HTTP request/response logging
- ✅ Cache-first strategy
- ✅ Network-first strategy
- ✅ Force-cache strategy
- ✅ Cache invalidation
- ✅ Request deduplication
- ✅ Angular Signals based HTTP resource
- ✅ Tree-shakable
- ✅ Lightweight
- ✅ Production ready
- ✅ No dependency on
@kudoengineer/loader
📦 Installation
Install the package using npm:
npm install @kudoengineer/http🔧 Requirements
Supported Angular versions:
- Angular 20
- Angular 21
- Angular 22
- Angular 23
The package requires:
@angular/common
@angular/core🚀 Basic Setup
1. Import providers
In your Angular application, add:
import { ApplicationConfig } from '@angular/core';
import { provideKudoHttp, provideKudoHttpInterceptors } from '@kudoengineer/http';
export const appConfig: ApplicationConfig = {
providers: [
provideKudoHttp({
baseUrl: 'https://api.example.com',
}),
provideKudoHttpInterceptors(),
],
};🌐 Base URL
Configure a global API base URL:
provideKudoHttp({
baseUrl: 'https://api.example.com',
});Now:
this.http.get('/users');will request:
https://api.example.com/usersYou can also provide an absolute URL:
this.http.get('https://another-api.com/users');Absolute URLs are not modified by the configured base URL.
📡 HTTP Service
Inject KudoHttpService:
import { Component, inject } from '@angular/core';
import { KudoHttpService } from '@kudoengineer/http';
@Component({
selector: 'app-users',
standalone: true,
template: `...`,
})
export class UsersComponent {
private readonly http = inject(KudoHttpService);
}GET Request
this.http.get<User[]>('/users').subscribe((users) => {
console.log(users);
});POST Request
this.http
.post<User>('/users', {
name: 'Satendra',
email: '[email protected]',
})
.subscribe((user) => {
console.log(user);
});PUT Request
this.http
.put<User>('/users/1', {
name: 'Satendra Rajput',
})
.subscribe((user) => {
console.log(user);
});PATCH Request
this.http
.patch<User>('/users/1', {
name: 'Satendra',
})
.subscribe((user) => {
console.log(user);
});DELETE Request
this.http.delete('/users/1').subscribe(() => {
console.log('User deleted');
});HEAD Request
this.http.head('/users').subscribe((headers) => {
console.log(headers);
});OPTIONS Request
this.http.options('/users').subscribe((response) => {
console.log(response);
});🧾 Headers
Global Headers
Configure headers globally:
provideKudoHttp({
baseUrl: 'https://api.example.com',
headers: {
'Content-Type': 'application/json',
'X-Client': 'KudoEngineer',
},
});Request Headers
You can override/add headers for an individual request:
this.http.get('/users', {
headers: {
'X-Request-Type': 'admin',
},
});🔎 Query Parameters
Pass query parameters using an object:
this.http.get('/users', {
params: {
page: 1,
size: 20,
active: true,
},
});Generated URL:
/users?page=1&size=20&active=true🔐 Authentication
@kudoengineer/http supports custom token providers.
Create a token provider:
const tokenProvider = {
getAccessToken: () => {
return localStorage.getItem('access_token');
},
};Configure authentication:
provideKudoHttpAuth(tokenProvider);Complete configuration:
import { provideKudoHttpAuth } from '@kudoengineer/http';
providers: [provideKudoHttpAuth(tokenProvider)];The default header is:
Authorization: Bearer <token>🪪 Custom Authentication Header
provideKudoHttpAuth(tokenProvider, {
headerName: 'X-Auth-Token',
scheme: '',
});🚫 Exclude URLs from Authentication
provideKudoHttpAuth(tokenProvider, {
excludedUrls: ['/auth/login', '/auth/register', '/public'],
});🎯 Include URLs
You can restrict authentication to specific URLs:
provideKudoHttpAuth(tokenProvider, {
includeUrls: ['/api/', '/secure/'],
});🔄 Retry
Enable global retry:
provideKudoHttp({
baseUrl: 'https://api.example.com',
retry: {
enabled: true,
count: 3,
delay: 500,
maxDelay: 5000,
},
});Default retryable status codes:
408
429
500
502
503
504Network errors can also be retried.
🎯 Request-specific Retry
this.http.get('/users', {
retry: {
enabled: true,
count: 5,
delay: 1000,
maxDelay: 10000,
},
});Request-level configuration overrides the global retry configuration.
⏱️ Timeout
Global timeout:
provideKudoHttp({
timeout: 30000,
});Request-specific timeout:
this.http.get('/users', {
timeout: 10000,
});The value is in milliseconds.
🛑 Request Cancellation
Use the standard AbortController API:
const controller = new AbortController();
this.http
.get('/users', {
signal: controller.signal,
})
.subscribe({
next: (data) => {
console.log(data);
},
error: (error) => {
console.error(error);
},
});Cancel the request:
controller.abort();❌ Error Handling
The package normalizes HTTP errors into:
KudoHttpError;Example:
this.http.get('/users').subscribe({
next: (users) => {
console.log(users);
},
error: (error) => {
console.log(error.status);
console.log(error.message);
console.log(error.code);
},
});Available error codes include:
HTTP_ERROR
NETWORK_ERROR
TIMEOUT
UNKNOWN_ERRORYou can also configure a global error handler:
provideKudoHttp({
onError: (error) => {
console.error('[KudoHttp]', error);
},
});🆔 Request ID
Request IDs are enabled by default.
Every request receives:
X-Request-IDExample:
X-Request-ID: 9c3d7...This is useful for:
- distributed tracing
- debugging
- backend log correlation
- microservices
- fintech applications
📝 Logging
Logging is disabled by default.
Enable it:
provideKudoHttpInterceptors({
logging: true,
});Example console output:
[KudoHttp] HTTP_REQUEST
[KudoHttp] HTTP_RESPONSELogging can include:
- request method
- URL
- request ID
- status
- status text
- duration
Sensitive headers and body data are not logged by default.
💾 Cache
Caching is opt-in per request.
Cache First
this.http.get('/users', {
cache: {
policy: 'cache-first',
ttl: 60000,
},
});The cache is checked first.
If cached data exists, it is returned without making a network request.
🌐 Network First
this.http.get('/users', {
cache: {
policy: 'network-first',
ttl: 60000,
},
});The network is requested first.
If the network request fails and valid cached data exists, cached data is returned.
This is useful for:
- dashboards
- configuration APIs
- offline-friendly applications
- mobile applications
⚡ Force Cache
this.http.get('/users', {
cache: {
policy: 'force-cache',
ttl: 60000,
},
});Cached data is used when available.
🚫 Disable Cache
this.http.get('/users', {
cache: {
policy: 'no-cache',
},
});🗑️ Cache Invalidation
Inject:
import { KudoCacheService } from '@kudoengineer/http';Then:
private readonly cache =
inject(KudoCacheService);Clear all cache:
this.cache.clear();Invalidate a URL:
this.cache.invalidate('/users');Check cache:
this.cache.has('GET:/users');Get cache size:
this.cache.size();🔁 Request Deduplication
Request deduplication prevents multiple identical GET requests from being sent simultaneously.
Enable it:
this.http.get('/users', {
deduplicate: true,
});If multiple components request:
this.http.get('/users', {
deduplicate: true,
});at the same time, the requests can share the same in-flight observable instead of creating unnecessary duplicate network calls.
Deduplication is intended for GET requests.
📶 Angular Signals HTTP Resource
Modern Angular applications can use the Signals-based HTTP resource API.
Inject:
import { KudoHttpResourceService } from '@kudoengineer/http';private readonly resource =
inject(KudoHttpResourceService);Create a resource:
usersResource = this.resource.create(() => this.http.get<User[]>('/users'));Execute:
this.usersResource.execute();📊 Signals
The resource provides:
usersResource.data();usersResource.loading();usersResource.success();usersResource.error();usersResource.status();🧩 Angular Template Example
@if (usersResource.loading()) {
<p>Loading users...</p>
} @if (usersResource.error()) {
<p>{{ usersResource.error()?.message }}</p>
} @if (usersResource.success()) {
<p>Users loaded successfully.</p>
} @for ( user of usersResource.data() ?? []; track user.id ) {
<p>{{ user.name }}</p>
}🔄 Reset Resource
this.usersResource.reset();This resets:
- data
- loading
- success
- error
- status
🧹 Destroy Resource
this.usersResource.destroy();This unsubscribes from the active request.
⚙️ Interceptor Configuration
All built-in interceptors can be configured:
provideKudoHttpInterceptors({
auth: true,
error: true,
retry: true,
cache: true,
logging: false,
requestId: true,
deduplication: true,
});🎛️ Disable Interceptors
For example, disable logging:
provideKudoHttpInterceptors({
logging: false,
});Disable retry:
provideKudoHttpInterceptors({
retry: false,
});Disable caching:
provideKudoHttpInterceptors({
cache: false,
});🏗️ Recommended Production Setup
import { ApplicationConfig } from '@angular/core';
import {
provideKudoHttp,
provideKudoHttpAuth,
provideKudoHttpInterceptors,
} from '@kudoengineer/http';
const tokenProvider = {
getAccessToken: () => {
return localStorage.getItem('access_token');
},
};
export const appConfig: ApplicationConfig = {
providers: [
provideKudoHttp({
baseUrl: 'https://api.example.com',
timeout: 30000,
retry: {
enabled: true,
count: 3,
delay: 500,
maxDelay: 5000,
},
onError: (error) => {
console.error('[API Error]', error);
},
}),
provideKudoHttpAuth(tokenProvider, {
excludedUrls: ['/auth/login', '/auth/register'],
}),
provideKudoHttpInterceptors({
auth: true,
error: true,
retry: true,
cache: true,
logging: false,
requestId: true,
deduplication: true,
}),
],
};🧱 Architecture
@kudoengineer/http
│
├── core
│ ├── KudoHttpService
│ ├── KudoHttpResource
│ ├── HttpRequest
│ ├── HttpResponse
│ └── HttpError
│
├── config
│ ├── HttpConfig
│ ├── Defaults
│ └── Providers
│
├── auth
│ ├── TokenProvider
│ ├── AuthConfig
│ └── AuthInterceptor
│
├── interceptors
│ ├── Auth
│ ├── Error
│ ├── Retry
│ ├── Cache
│ ├── Logging
│ ├── Request ID
│ └── Deduplication
│
├── cache
│ ├── CacheStore
│ ├── CacheService
│ ├── CacheEntry
│ └── CachePolicy
│
├── retry
│ ├── RetryPolicy
│ ├── Backoff
│ └── RetryContext
│
└── utils
├── Headers
├── Params
└── Request ID📚 API Overview
KudoHttpService
get()
post()
put()
patch()
delete()
head()
options()KudoHttpResourceService
create()KudoHttpResource
data
loading
success
error
status
execute()
reset()
destroy()KudoCacheService
clear()
invalidate()
delete()
has()
size()
keys()KudoCacheStore
get()
set()
delete()
clear()
has()
size()
keys()
deleteByUrl()🔒 Security Recommendations
For production applications:
- Never log access tokens.
- Never enable body/header logging without reviewing sensitive data.
- Prefer secure token storage appropriate to your application's security model.
- Use HTTPS for production APIs.
- Avoid caching sensitive responses unless explicitly required.
- Configure authentication exclusions carefully.
- Use request IDs for backend traceability.
🌐 Links
KudoEngineer
https://kudoengineer.com
NPM Package
https://www.npmjs.com/package/@kudoengineer/http
👨💻 Author
Satendra Rajput
Software Engineer | Angular | Java | Spring Boot
Website:
https://kudoengineer.com
📄 License
MIT License
Copyright © Satendra Rajput
⭐ Support
If @kudoengineer/http helps your Angular project, consider giving the project a ⭐ and sharing it with other Angular developers.
Built with ❤️ by KudoEngineer
