@salespark/http-request
v1.0.0
Published
A lightweight TypeScript wrapper around Axios that standardizes all HTTP responses into the global SalesParkContract<T> format, supports global and per-request options, and provides a clean, consistent API for GET/POST/PUT/DELETE requests.
Readme
SalesPark HTTP Request Client - Documentation
@salespark/http-request
A lightweight TypeScript wrapper around Axios that standardizes all HTTP responses into the global SalesParkContract format, supports global and per-request options, and provides a clean, consistent API for GET/POST/PUT/DELETE requests.
🧭 Overview
@salespark/http-request is a minimalist HTTP client built on top of Axios, designed to provide a consistent response format across all HTTP operations. It enforces the SalesParkContract<T> response model ({ status: boolean, data: T }), never throws exceptions, and includes built-in global header management.
This package is part of the SalesPark Libraries ecosystem and follows the same patterns and conventions used across all SalesPark packages.
📦 Installation
yarn add @salespark/http-request
# or
npm install @salespark/http-request🚀 Quick Start
import { HttpClient } from '@salespark/http-request';
// Initialize the client
const httpClient = new HttpClient({
baseURL: 'https://api.example.com',
timeout: 10000,
headers: {
'Content-Type': 'application/json'
}
});
// Make requests - all return SalesParkContract<T>
const user = await httpClient.get('/users/1');
if (user.status) {
console.log('User:', user.data);
} else {
console.error('Error:', user.data);
}
// Create a new resource
const newPost = await httpClient.post('/posts', {
title: 'Hello World',
body: 'My first post'
});
if (newPost.status) {
console.log('Created post with ID:', newPost.data.id);
}⚙️ Configuration Options
The HttpClient constructor accepts the following options:
| Option | Type | Description | Default |
| --------- | --------------------------- | ------------------------------------- | ------- |
| baseURL | string | Base URL for all requests | - |
| timeout | number | Request timeout in milliseconds | 15000 |
| headers | Record<string, string> | Default headers for all requests | {} |
🧩 Available Methods
All methods return a Promise that resolves to the SalesParkContract<T> format:
interface SalesParkContract<T = any> {
status: boolean;
data: T;
}🔹 HTTP Methods
| Method | Description | Example |
| ---------------------------------------- | ---------------------------------- | ---------------------------------------------------- |
| get<T>(url, options?) | Execute GET request | httpClient.get<User>('/users/1') |
| post<T>(url, body?, options?) | Execute POST request | httpClient.post('/users', { name: 'John' }) |
| put<T>(url, body?, options?) | Execute PUT request | httpClient.put('/users/1', { name: 'Jane' }) |
| delete<T>(url, options?) | Execute DELETE request | httpClient.delete('/users/1') |
| setHeader(key, value) | Set/update global header | httpClient.setHeader('Authorization', 'Bearer ...') |
🔹 Request Options
All HTTP methods accept optional RequestOptions (extends Axios AxiosRequestConfig):
interface RequestOptions extends AxiosRequestConfig {
params?: any;
headers?: Record<string, string>;
timeout?: number;
// ... other Axios options
}🧠 Detailed Usage Examples
Basic GET Request
import { HttpClient } from '@salespark/http-request';
const client = new HttpClient({
baseURL: 'https://jsonplaceholder.typicode.com'
});
// Fetch a single user
const user = await client.get('/users/1');
if (user.status) {
console.log('User name:', user.data.name);
console.log('User email:', user.data.email);
} else {
console.error('Failed to fetch user:', user.data);
}GET with Query Parameters
// Fetch posts with query parameters
const posts = await client.get('/posts', {
params: {
userId: 1,
_limit: 5
}
});
if (posts.status) {
console.log(`Found ${posts.data.length} posts`);
posts.data.forEach(post => console.log(post.title));
}POST Request - Creating Resources
// Create a new post
const newPost = await client.post('/posts', {
title: 'My New Post',
body: 'This is the content of my post',
userId: 1
});
if (newPost.status) {
console.log('Created post with ID:', newPost.data.id);
} else {
console.error('Failed to create post:', newPost.data);
}PUT Request - Updating Resources
// Update an existing post
const updatedPost = await client.put('/posts/1', {
id: 1,
title: 'Updated Post Title',
body: 'Updated content',
userId: 1
});
if (updatedPost.status) {
console.log('Post updated successfully');
} else {
console.error('Update failed:', updatedPost.data);
}DELETE Request
// Delete a post
const deleteResult = await client.delete('/posts/1');
if (deleteResult.status) {
console.log('Post deleted successfully');
} else {
console.error('Delete failed:', deleteResult.data);
}Global Header Management
const client = new HttpClient({
baseURL: 'https://api.example.com'
});
// Set authorization header for all subsequent requests
client.setHeader('Authorization', 'Bearer your-jwt-token');
// Set custom headers
client.setHeader('X-API-Version', 'v1');
client.setHeader('X-Client-ID', 'my-app');
// All requests will now include these headers
const protectedData = await client.get('/protected-endpoint');Advanced Configuration
const client = new HttpClient({
baseURL: 'https://api.example.com',
timeout: 30000, // 30 seconds
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
}
});
// Make request with custom options
const result = await client.get('/data', {
timeout: 5000, // Override default timeout for this request
headers: {
'Cache-Control': 'no-cache' // Additional header for this request
},
params: {
page: 1,
limit: 20
}
});🧱 Response Model
All methods return the standardized SalesParkContract<T> format:
✅ Success Response
{
status: true,
data: T // The actual response data from the API
}❌ Error Response
{
status: false,
data: any // The error object/information
}TypeScript Usage
interface User {
id: number;
name: string;
email: string;
}
const userResponse = await client.get<User>('/users/1');
if (userResponse.status) {
// TypeScript knows userResponse.data is of type User
console.log(userResponse.data.name);
console.log(userResponse.data.email);
} else {
// Handle error case
console.error('Error:', userResponse.data);
}🛡️ Error Handling
The client never throws exceptions. All errors are captured and returned in the standardized format:
// Network error, timeout, or HTTP error - all handled consistently
const result = await client.get('/non-existent-endpoint');
if (!result.status) {
// Handle all types of errors uniformly
console.error('Request failed:', result.data);
// Error data might contain:
// - Network errors
// - HTTP status codes (404, 500, etc.)
// - Timeout errors
// - Request cancellation
}Common Error Scenarios
// Handle different error types
const response = await client.get('/api/data');
if (!response.status) {
const error = response.data;
if (error.code === 'NETWORK_ERROR') {
console.log('Check your internet connection');
} else if (error.code === 'TIMEOUT') {
console.log('Request timed out');
} else if (error.response?.status === 404) {
console.log('Resource not found');
} else if (error.response?.status === 401) {
console.log('Unauthorized - check your authentication');
} else {
console.log('Unexpected error:', error.message);
}
}🧪 Testing
The package includes comprehensive tests using Jest and real API calls to JSONPlaceholder:
# Run tests
yarn test
# Run tests in watch mode
yarn test:watch
# Run tests with coverage
yarn test:coverageTest Coverage
- ✅ Constructor initialization
- ✅ GET requests (single resources, collections, query parameters)
- ✅ POST requests (create resources, comments)
- ✅ PUT requests (update resources)
- ✅ DELETE requests
- ✅ Global header management
- ✅ Error handling (network errors, timeouts, 404s)
- ✅ Response standardization
- ✅ Complete CRUD operations
🏷️ TypeScript Support
The package is written in TypeScript and provides full type safety:
import { HttpClient, SalesParkContract } from '@salespark/http-request';
// Fully typed client
const client = new HttpClient({
baseURL: 'https://api.example.com',
timeout: 10000
});
// Typed responses
interface Product {
id: number;
name: string;
price: number;
}
const product: SalesParkContract<Product> = await client.get<Product>('/products/1');
if (product.status) {
// TypeScript knows product.data is of type Product
console.log(`${product.data.name} costs $${product.data.price}`);
}📋 API Reference
Class: HttpClient
Constructor
constructor(options?: HttpClientOptions)Methods
get<T>(url: string, options?: RequestOptions): Promise<SalesParkContract<T>>
- Execute GET request
- Returns typed response wrapped in SalesParkContract
post<T>(url: string, body?: any, options?: RequestOptions): Promise<SalesParkContract<T>>
- Execute POST request with optional body
- Returns typed response wrapped in SalesParkContract
put<T>(url: string, body?: any, options?: RequestOptions): Promise<SalesParkContract<T>>
- Execute PUT request with optional body
- Returns typed response wrapped in SalesParkContract
delete<T>(url: string, options?: RequestOptions): Promise<SalesParkContract<T>>
- Execute DELETE request
- Returns typed response wrapped in SalesParkContract
setHeader(key: string, value: string): void
- Set or update a global header that will be sent with all subsequent requests
Interfaces
interface HttpClientOptions {
baseURL?: string;
timeout?: number;
headers?: Record<string, string>;
}
interface RequestOptions extends AxiosRequestConfig {
// Inherits all Axios request configuration options
}
interface SalesParkContract<T = any> {
status: boolean;
data: T;
}🔄 Integration with Other SalesPark Packages
This package follows the SalesPark ecosystem patterns and works seamlessly with:
- @salespark/toolkit - Utility functions for data processing
- @salespark/api-client - Higher-level API client for React applications
- @salespark/mongo-repo-utils - MongoDB utilities for backend services
Example with @salespark/toolkit
import { HttpClient } from '@salespark/http-request';
import { debounce, formatCurrency } from '@salespark/toolkit';
const client = new HttpClient({
baseURL: 'https://api.example.com'
});
// Debounced search function
const searchProducts = debounce(async (query: string) => {
const result = await client.get('/products/search', {
params: { q: query }
});
if (result.status) {
return result.data.map(product => ({
...product,
formattedPrice: formatCurrency(product.price)
}));
}
return [];
}, 300);🛠️ Support
Got stuck? Don't panic — we've got you covered.
🤖 AI Assistant
We built a custom AI Assistant trained only on @salespark/http-request.
It answers implementation and troubleshooting questions in real time:
👉 Ask the HTTP Request Client GPT:
https://chatgpt.com/g/g-[YOUR-GPT-ID]-salespark-http-request
(Free to use with a ChatGPT account)
🔒 Internal Usage Notice
This package is primarily designed and maintained for internal use within the SalesPark ecosystem. While it can technically be used in other TypeScript/JavaScript projects, no official support or guarantees are provided outside of SalesPark-managed projects.
All code follows the same engineering standards applied across the SalesPark platform, ensuring consistency, reliability, and long-term maintainability of our internal systems.
⚡ Note: This package is most efficient and works best when used together with other official SalesPark packages, where interoperability and optimizations are fully leveraged.
Disclaimer: This software is provided "as is", without warranties of any kind, express or implied. SalesPark shall not be held liable for any issues, damages, or losses arising from its use outside the intended SalesPark environment.
Organization packages: https://www.npmjs.com/org/salespark
📄 License
MIT © SalesPark
Document version: 1
Last update: 13-11-2025
