A highly maintainable, type-safe TypeScript API wrapper that provides excellent developer experience through configuration-driven endpoint management.
- π§ Configuration-Driven: Add new endpoints by simply updating the configuration file
- π Type Safety: Full TypeScript support with intelligent IntelliSense
- β Automatic Validation: Request/response validation with detailed error messages
- π Smart Retries: Configurable retry logic with exponential backoff
- π Built-in Logging: Request/response logging for debugging
- π― Path Parameters: Automatic handling of dynamic URL parameters
- π Extensible: Easy to extend with custom business logic
npm install api-wrapper-sdk
# or
yarn add api-wrapper-sdkThis package follows a configuration-driven architecture that prioritizes maintainability:
src/
βββ types.ts # Core type definitions
βββ endpoints.ts # π― ENDPOINT CONFIGURATIONS (Main file to modify)
βββ validator.ts # Request/response validation logic
βββ http-client.ts # HTTP client with retry logic
βββ api-client.ts # Main API client class
βββ index.ts # Public API exports
When you need to add a new endpoint, you ONLY need to modify src/endpoints.ts. The entire system automatically:
- Generates type-safe methods
- Handles validation
- Provides IntelliSense support
- Manages path parameters
import { createApiClient } from 'api-wrapper-sdk';
const apiClient = createApiClient({
baseURL: 'https://api.example.com',
timeout: 30000,
retries: 3,
retryDelay: 1000,
defaultHeaders: {
'Authorization': 'Bearer your-token-here',
'Content-Type': 'application/json'
}
});// Get users with pagination
const users = await apiClient.getUsers({
page: 1,
limit: 10,
search: 'john'
});
// Get specific user
const user = await apiClient.getUserById(123);
// Create new user
const newUser = await apiClient.createUser({
name: 'John Doe',
email: 'john@example.com',
password: 'securepassword123'
});
// Update user
const updatedUser = await apiClient.updateUser(123, {
name: 'John Updated'
});This is where the magic happens! To add a new endpoint, you ONLY need to update src/endpoints.ts:
// In src/endpoints.ts
export interface ProductQueryParams {
category?: string;
minPrice?: number;
maxPrice?: number;
}
export interface ProductResponse {
id: number;
name: string;
price: number;
category: string;
}
export interface CreateProductBody {
name: string;
price: number;
category: string;
description?: string;
}// In src/endpoints.ts - Add to API_ENDPOINTS object
export const API_ENDPOINTS = {
// ... existing endpoints ...
getProducts: {
path: '/products',
method: 'GET' as HttpMethod,
queryParams: {
category: { type: 'string', description: 'Filter by category' },
minPrice: { type: 'number', description: 'Minimum price filter' },
maxPrice: { type: 'number', description: 'Maximum price filter' }
},
description: 'Get products with filtering options'
} as EndpointConfig<ProductQueryParams, never, ProductResponse[]>,
createProduct: {
path: '/products',
method: 'POST' as HttpMethod,
requestBody: {
name: { required: true, type: 'string', description: 'Product name' },
price: { required: true, type: 'number', description: 'Product price' },
category: { required: true, type: 'string', description: 'Product category' },
description: { type: 'string', description: 'Product description' }
},
description: 'Create a new product'
} as EndpointConfig<never, CreateProductBody, ProductResponse>
};// In src/api-client.ts - Add to ApiClient class
async getProducts(queryParams?: ProductQueryParams) {
return this.get('getProducts', queryParams);
}
async createProduct(productData: CreateProductBody) {
return this.post('createProduct', productData);
}That's it! The new endpoints are now fully functional with:
- β Type safety
- β Validation
- β IntelliSense support
- β Error handling
interface ClientConfig {
baseURL: string; // API base URL
defaultHeaders?: Headers; // Default headers for all requests
timeout?: number; // Request timeout (ms)
retries?: number; // Number of retry attempts
retryDelay?: number; // Delay between retries (ms)
}interface EndpointConfig {
path: string; // URL path (supports :id parameters)
method: HttpMethod; // HTTP method
queryParams?: { // Query parameter validation schema
[key]: {
required?: boolean;
type: 'string' | 'number' | 'boolean';
description?: string;
};
};
requestBody?: { // Request body validation schema
[key]: {
required?: boolean;
type: 'string' | 'number' | 'boolean' | 'object' | 'array';
description?: string;
};
};
headers?: Headers; // Endpoint-specific headers
timeout?: number; // Endpoint-specific timeout
description?: string; // Endpoint description
}The SDK provides detailed error information:
try {
await apiClient.createUser({
name: 'John',
// email missing - validation error
});
} catch (error) {
if (error.name === 'ApiValidationError') {
console.log('Validation errors:', error.errors);
// [{ field: 'email', message: 'Required field is missing', expectedType: 'string', actualValue: undefined }]
} else if (error.name === 'ApiRequestError') {
console.log('Request failed:', {
status: error.status,
statusText: error.statusText,
response: error.response
});
}
}class CustomApiClient extends ApiClient {
async getUserWithPosts(userId: number) {
const [user, posts] = await Promise.all([
this.getUserById(userId),
this.getPosts({ authorId: userId })
]);
return { user: user.data, posts: posts.data };
}
}// For dynamic endpoint calls
const response = await apiClient.request('getUsers', {
queryParams: { limit: 5 },
headers: { 'Custom-Header': 'value' }
});// Endpoints with :id parameters are handled automatically
await apiClient.getUserById(123); // GET /users/123
await apiClient.updateUser(123, userData); // PUT /users/123
await apiClient.deleteUser(123); // DELETE /users/123All requests are automatically logged:
[API] GET /users?page=1&limit=10
[API] Response 200 for /users?page=1&limit=10
Failed requests are automatically retried based on configuration:
[API] Retrying request (1/3)
All responses are properly typed:
const response = await apiClient.getUsers();
// response.data is typed as UserResponse[]
// response.status is number
// response.headers is Headersnpm test# Install dependencies
npm install
# Build the package
npm run build
# Watch mode for development
npm run dev
# Lint code
npm run lint
# Format code
npm run formatWe welcome contributions to the API Wrapper SDK! Here's how you can contribute:
- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/your-username/api-wrapper-sdk.git cd api-wrapper-sdk - Install dependencies:
npm install
- Create a feature branch:
git checkout -b feature/your-feature-name
-
Make your changes following our coding standards:
- Add new endpoints by updating
src/endpoints.ts - Add convenience methods to
src/api-client.tsif needed - Write tests for new functionality in
src/__tests__/
- Add new endpoints by updating
-
Test your changes:
npm test # Run all tests npm run lint # Check code style npm run format # Format code npm run build # Ensure build works
-
Update documentation if needed:
- Update README.md for new features
- Add JSDoc comments to new functions
- Update type definitions
- Code Style: We use ESLint and Prettier for consistent code formatting
- Commit Messages: Use clear, descriptive commit messages
- Testing: Add tests for new features and ensure existing tests pass
- Documentation: Update documentation for any new features or changes
- Type Safety: Maintain full TypeScript compatibility
- π Bug fixes
- β¨ New features (new endpoints, client improvements)
- π Documentation improvements
- π§ͺ Tests (unit tests, integration tests)
- π¨ Code style improvements
- β‘ Performance improvements
- Commit your changes:
git add . git commit -m "feat: add amazing new feature"
- Push to your fork:
git push origin feature/your-feature-name
- Create a Pull Request on GitHub with:
- Clear description of changes
- Reference to any related issues
- Screenshots/examples if applicable
- All submissions require review
- We aim to review PRs within 48 hours
- Address feedback promptly
- Ensure CI checks pass
- Check existing issues
- Create a new issue for bugs or feature requests
- Join discussions in existing issues
This project is licensed under the MIT License - see the LICENSE file for details.
- β Commercial use - You can use this software commercially
- β Modification - You can modify the source code
- β Distribution - You can distribute the software
- β Private use - You can use this software privately
- β Liability - Authors are not liable for any damages
- β Warranty - No warranty is provided
Copyright (c) 2025 akhshyganesh
This configuration-driven approach provides several key benefits:
- Maintainability: New endpoints require changes to only one file
- Type Safety: Full TypeScript support with intelligent IntelliSense
- Consistency: All endpoints follow the same patterns
- Validation: Automatic request/response validation
- Documentation: Self-documenting through configuration
- Testability: Easy to mock and test individual endpoints
- Scalability: Scales effortlessly as your API grows
The result is a codebase that remains clean and maintainable even as you add dozens or hundreds of endpoints!