Lightweight zero-dependency HTTP client built on top of `fetch` with TypeScript support
npm install @quarnel/httpclientfetch with TypeScript support
Content-Type: application/json for object bodies
FormData, Blob, URLSearchParams
AbortController
AbortSignal
Accept: application/json by default
HttpError with status, body & headers
bash
npm install @quarnel/httpclient
`
Usage
`ts
import { HttpClient, HttpError } from '@quarnel/httpclient'
type User = {
name: string
}
const client = new HttpClient({
baseUrl: 'https://api.com',
headers: {
Authorization: 'Bearer your-token-here',
'X-Custom-Header': 'value',
},
timeout: 15000, // ms
retry: {
attempts: 3,
delay: 1000, // ms
},
throwOnHttpError: true, // default true
})
async function exampleFetch() {
try {
const res = await client.get('/users', {
query: { profile: 20, name: 'quarnel' }, // https://api.com/users?profile=20&name=quarnel
})
console.log(res.status) // HTTP status
console.log(res.data.name) // typed User
console.log(res.headers) // headers
} catch (err) {
if (err instanceof HttpError) {
console.error( HTTP ${err.status}: , err.body)
} else {
console.error('Network/Abort error: ', err)
}
}
}
`
$3
`ts
const form = new FormData()
form.append('avatar', file)
form.append('name', 'Quarnel')
await client.post('/profile/update', form)
`
$3
`ts
const controller = new AbortController()
client.get('/longfetch', { signal: controller.signal })
controller.abort()
`
API
- get
GET request with generics to type the response
- post
POST request, automatically sets Content-Type: application/json
- put, delete, patch
Similarly, they support body and config.
Client configuration (HttpClientConfig):
- baseUrl?: string — prefix for all URLs
- headers?: CommonHeaders — default headers (with auto-completion)
- timeout?: number — timeout in ms
- retry?: { attempts: number; delay: number } — repeated attempts
- throwOnHttpError?: boolean — throws an error at 4xx/5xx (true by default)
Request Configuration (RequestConfig):
- query?: Record — query parameters
- headers?: CommonHeaders — headers for a specific request
- signal?: AbortSignal — to cancel the request
- timeout?: number — redefining the timeout
Response Type (HttpResponse):
`ts
export interface HttpResponse {
status: number // HTTP status code
data: T // Parsed response body (JSON or text)
headers: Record // Response headers as object
}
`
type CommonHeaders:
`ts
export type CommonHeaders = {
Authorization?: Bearer ${string} | Basic ${string} | string
'X-API-Key'?: string
'Api-Key'?: string
'Content-Type'?: 'application/json' | 'application/x-www-form-urlencoded' | 'text/plain' | 'application/octet-stream' | string
Accept?: 'application/json' | 'text/plain' | '/' | string
'Accept-Language'?: string
'Cache-Control'?: 'no-cache' | 'no-store' | 'max-age=0' | max-age=${number} | string
'If-None-Match'?: string
'If-Modified-Since'?: string
Origin?: string
Referer?: string
'X-Requested-With'?: 'XMLHttpRequest'
'X-CSRF-Token'?: string
'X-Request-ID'?: string
'X-Client-Version'?: string
'X-App-Version'?: string
'User-Agent'?: string
} & Record
`
Errors:
- HttpError — thrown when !res.ok and throwOnHttpError is true
Contains:
- status: number
- body: unknown (parsed JSON or text)
- headers: Record