util-http
v0.0.15
Published
util-http
Maintainers
Readme
util-http
util-http es un módulo de utilidades para realizar solicitudes HTTP con diversas opciones y clientes.
ADVERTENCIA: Asegúrate de configurar correctamente las opciones del cliente antes de realizar solicitudes.
Indice
- Instalacion
- Clientes disponibles
- Configuracion del cliente (ClientConfig)
- Opciones por solicitud (ClientOptions)
- Manejo de errores (CustomError)
- AxiosClient
- FetchClient
- UndiciClient
- SuperAgentClient
- HttpClient
- TypeScript
Instalacion
npm install util-http
# o
pnpm add util-httpClientes disponibles
| Cliente | Descripcion |
| --- | --- |
| AxiosClient | Basado en axios |
| FetchClient | Basado en la Fetch API nativa |
| UndiciClient | Basado en undici (alto rendimiento) |
| SuperAgentClient | Basado en superagent (isomorphic: Node.js + browser) |
| HttpClient | Agrupador que expone los cuatro clientes y utilidades estaticas |
Configuracion del cliente — ClientConfig
Se pasa al constructor de cada cliente para establecer valores por defecto que se aplican a todas las solicitudes.
interface ClientConfig {
baseURL?: string;
timeout?: number;
headers?: Record<string, string>;
contentTypes?: Record<string, "json" | "urlencoded" | "formData" | "text" | "buffer">;
onError?: (error: CustomError) => CustomError;
}| Opcion | Tipo | Descripcion |
| --- | --- | --- |
| baseURL | string | URL base que se antepone a todas las rutas relativas |
| timeout | number | Tiempo de espera en ms (por defecto 15000) |
| headers | Record<string, string> | Cabeceras globales para todas las solicitudes |
| contentTypes | Record<string, ContentTypeHandlerKey> | Extiende el mapa de Content-Type para parsear respuestas personalizadas |
| onError | (error: CustomError) => CustomError | Hook que intercepta y transforma el error antes de lanzarlo |
import { AxiosClient } from "util-http";
const client = new AxiosClient({
baseURL: "https://api.example.com",
timeout: 5000,
headers: { Authorization: "Bearer token" },
onError: (err) => {
console.error("Request failed:", err.message);
return err;
}
});Opciones por solicitud — ClientOptions
Se pasan a cada llamada individual y tienen prioridad sobre la configuracion del cliente.
interface ClientOptions {
url: string;
method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS";
headers?: Record<string, string>;
data?: string | FormData | URLSearchParams | Record<string, unknown>;
params?: Record<string, string | number | boolean>;
timeout?: number;
responseType?: "json" | "urlencoded" | "formData" | "text" | "buffer";
}| Opcion | Tipo | Descripcion |
| --- | --- | --- |
| url | string | URL de la solicitud (absoluta o relativa si hay baseURL) |
| method | Method | Metodo HTTP |
| headers | Record<string, string> | Cabeceras adicionales (se mezclan con las globales; estas tienen prioridad) |
| data | varios | Cuerpo. FormData y URLSearchParams se envian tal cual; los objetos se serializan como JSON |
| params | Record<string, string \| number \| boolean> | Parametros de query string que se adjuntan a la URL |
| timeout | number | Sobreescribe el timeout del cliente para esta solicitud |
| responseType | ContentTypeHandlerKey | Fuerza un parser concreto independientemente del Content-Type de la respuesta |
Manejo de errores — CustomError
Todos los clientes lanzan instancias de CustomError en caso de fallo.
import { CustomError } from "util-http";
client.get({ url: "/users" }).catch((err: CustomError) => {
console.log(err.message); // mensaje de error
console.log(err.statusCode); // codigo HTTP (ej. 404, 503)
console.log(err.client); // "axios" | "fetch" | "undici"
console.log(err.timestamp); // ISO string del momento del error
console.log(err.extra); // datos adicionales de la respuesta
console.log(err.toJSON()); // representacion completa como objeto plano
err.log(); // imprime el error formateado en consola
});Mapeos automaticos:
| Condicion | statusCode | message |
| --- | --- | --- |
| ECONNREFUSED o respuesta HTML | 503 | "Unavailable Service" |
| ENOTFOUND o mensaje vacio | 404 | "Resource Not Found" |
| Resto de errores | el del servidor | el del servidor |
AxiosClient
Cliente basado en axios. Soporta todos los formatos de respuesta de axios incluido arraybuffer.
Metodos
client.get<T>(options)
client.post<T>(options)
client.put<T>(options)
client.patch<T>(options)
client.delete<T>(options)
client.head(options) // devuelve Record<string, string> con las cabeceras
client.options<T>(options)
client.request<T>(options) // incluye "method" en las opcionesEjemplo
import { AxiosClient } from "util-http";
const client = new AxiosClient({
baseURL: "https://api.example.com",
headers: { Authorization: "Bearer token" }
});
// GET con parametros de query
const users = await client.get<User[]>({
url: "/users",
params: { page: 1, limit: 20 }
});
// POST con cuerpo JSON
const user = await client.post<User>({
url: "/users",
data: { name: "Alice", email: "[email protected]" }
});
// GET de un archivo binario
const file = await client.get<ArrayBuffer>({
url: "/files/report.pdf",
responseType: "buffer"
});
// Usando request() directamente
const result = await client.request<User>({ url: "/users/1", method: "GET" });FetchClient
Cliente basado en la Fetch API nativa. Usa AbortSignal.timeout() para el control de tiempo de espera.
Metodos
client.get<T>(options)
client.post<T>(options)
client.put<T>(options)
client.patch<T>(options)
client.delete<T>(options)
client.request<T>(options)Ejemplo
import { FetchClient } from "util-http";
const client = new FetchClient({
baseURL: "https://api.example.com",
timeout: 8000,
contentTypes: { "application/vnd.api+json": "json" } // Content-Types personalizados
});
// Subir un fichero con FormData (no se serializa como JSON)
const formData = new FormData();
formData.append("avatar", file);
await client.post({ url: "/users/1/avatar", data: formData });
// Forzar lectura como texto independientemente del Content-Type
const html = await client.get<string>({
url: "/page",
responseType: "text"
});UndiciClient
Cliente basado en undici, el cliente HTTP de alto rendimiento de Node.js. Usa bodyTimeout y headersTimeout para el control de tiempo de espera.
Metodos
client.get<T>(options)
client.post<T>(options)
client.put<T>(options)
client.patch<T>(options)
client.delete<T>(options)
client.request<T>(options)Ejemplo
import { UndiciClient } from "util-http";
const client = new UndiciClient({
baseURL: "https://api.example.com",
timeout: 10000
});
// POST con URLSearchParams (se convierte a string automaticamente)
const params = new URLSearchParams({ grant_type: "client_credentials" });
const token = await client.post<TokenResponse>({
url: "/oauth/token",
data: params
});
// GET con query string
const results = await client.get<SearchResult[]>({
url: "/search",
params: { q: "typescript", sort: "stars" }
});SuperAgentClient
Cliente basado en superagent. Funciona tanto en Node.js como en el browser (isomorphic), lo que lo hace util para librerias universales.
Metodos
client.get<T>(options)
client.post<T>(options)
client.put<T>(options)
client.patch<T>(options)
client.delete<T>(options)
client.request<T>(options)Ejemplo
import { SuperAgentClient } from "util-http";
const client = new SuperAgentClient({
baseURL: "https://api.example.com",
timeout: 5000,
headers: { Authorization: "Bearer token" }
});
// GET con parametros de query
const users = await client.get<User[]>({
url: "/users",
params: { page: 1, active: true }
});
// POST con cuerpo JSON
const user = await client.post<User>({
url: "/users",
data: { name: "Alice", email: "[email protected]" }
});
// POST con FormData (los campos se envian via .field())
const formData = new FormData();
formData.append("avatar", file);
await client.post({ url: "/users/1/avatar", data: formData });
// GET de un archivo binario
const file = await client.get<ArrayBuffer>({
url: "/files/report.pdf",
responseType: "buffer"
});HttpClient
Agrupador que instancia los cuatro clientes con la misma configuracion. Tambien expone utilidades estaticas para construir URLs y parsear respuestas.
Uso como agrupador
import { HttpClient } from "util-http";
// Con configuracion compartida para los tres clientes
const http = new HttpClient({
baseURL: "https://api.example.com",
timeout: 5000
});
await http.axios.get({ url: "/users" });
await http.fetch.post({ url: "/users", data: { name: "Bob" } });
await http.undici.get({ url: "/health" });
await http.superagent.get({ url: "/status" });
// Instancia singleton (sin configuracion)
const singleton = HttpClient.getInstance();Utilidades estaticas
// Construye una URL completa concatenando baseURL y path
HttpClient.buildUrl("https://api.example.com", "/users");
// => "https://api.example.com/users"
// Construye URL con query string a partir de un objeto
HttpClient.buildUrlWithParams("https://api.example.com", "/search", { q: "ts", page: 1 });
// => "https://api.example.com/search?q=ts&page=1"
// Crea un mapa de handlers para parsear el body de la respuesta
const handlers = HttpClient.createContentHandlers();
// handlers.json(body) => body.json()
// handlers.text(body) => body.text()
// handlers.buffer(body) => body.arrayBuffer()
// Normaliza cualquier error a una instancia de CustomError
const err = HttpClient.handleErrors(rawError, 500, "fetch");TypeScript
Todos los tipos publicos se pueden importar directamente:
import type { ClientConfig, ClientOptions, ContentTypeHandlerKey, Client, Method } from "util-http";
import { CustomError, Constants } from "util-http";ContentTypeHandlerKey
type ContentTypeHandlerKey = "json" | "urlencoded" | "formData" | "text" | "buffer";Constants.contentTypes
Mapa completo de tipos MIME a ContentTypeHandlerKey incluido por defecto:
import { Constants } from "util-http";
console.log(Constants.contentTypes["application/json"]); // "json"
console.log(Constants.contentTypes["multipart/form-data"]); // "formData"
console.log(Constants.contentTypes["application/octet-stream"]); // "buffer"