@nebulae/tpiv2-interop-rest
v0.0.1
Published
Cliente REST resiliente con validación JSON Schema y manejo de errores
Readme
@nebulae/tpiv2-interop-rest
Cliente REST resiliente con validación JSON Schema y manejo de errores.
Instalación
npm install @nebulae/tpiv2-interop-rest @nebulae/tpiv2-interop-authUso
Cliente REST Básico
import { RestClient } from '@nebulae/tpiv2-interop-rest';
const client = new RestClient({
baseUrl: 'https://api.example.com',
retry: {
maxRetries: 3,
initialDelay: 1000,
},
});
const response = await client.get('/usuarios/123');
console.log(response.data);Con Autenticación
import { RestClient } from '@nebulae/tpiv2-interop-rest';
import { AuthClient } from '@nebulae/tpiv2-interop-auth';
const authClient = new AuthClient({ /* config */ });
const restClient = new RestClient({
baseUrl: 'https://api.example.com',
authClient, // Agrega automáticamente el token
});
const response = await restClient.get('/protected-resource');Con Validación de Esquemas
interface Usuario {
id: number;
nombre: string;
email: string;
}
const response = await restClient.get<Usuario>('/usuarios/123', {
responseSchema: {
type: 'object',
properties: {
id: { type: 'number' },
nombre: { type: 'string' },
email: { type: 'string', format: 'email' },
},
required: ['id', 'nombre', 'email'],
},
});Con Circuit Breaker
Cada RestClient incluye un CircuitBreaker propio. Si el servicio remoto falla
seguidas veces, el circuit breaker se abre (OPEN) y rechaza las llamadas subsiguientes
sin realizar el request HTTP, evitando saturar un endpoint ya degradado.
import { RestClient } from '@nebulae/tpiv2-interop-rest';
import { CircuitOpenError } from '@nebulae/tpiv2-interop-core';
const client = new RestClient({
baseUrl: 'https://api.example.com',
circuitBreaker: {
enabled: true,
failureThreshold: 5, // abre tras 5 fallas consecutivas
halfOpenTimeoutMs: 30000, // intenta recuperar tras 30 s
successThreshold: 2, // cierra tras 2 éxitos en HALF_OPEN
},
});
// Escuchar eventos de transición de estado
client.circuitBreaker.on('circuit:open', (event) => {
console.warn(`[CB] Circuito ABIERTO — fuente: ${event.source}, fallas: ${event.consecutiveFailures}`);
});
client.circuitBreaker.on('circuit:half-open', () => {
console.info('[CB] Circuito en HALF_OPEN — sondeando recuperación');
});
client.circuitBreaker.on('circuit:close', () => {
console.info('[CB] Circuito CERRADO — servicio recuperado');
});
// Manejar el rechazo cuando el circuito está abierto
try {
const response = await client.get('/resource');
} catch (error) {
if (error instanceof CircuitOpenError) {
console.error(`Circuito abierto (estado: ${error.circuitState}), request rechazado sin llamada HTTP`);
}
}Estados del circuit breaker:
| Estado | Descripción |
|--------|-------------|
| CLOSED | Operación normal; fallas se acumulan |
| OPEN | Todas las requests son rechazadas con CircuitOpenError |
| HALF_OPEN | Se permite una sonda; un éxito cierra, un fallo reabre |
Comportamiento especial para errores de autenticación: un único AuthenticationError
(token inválido/expirado) abre el circuito de inmediato (source: 'auth'), sin esperar
el umbral failureThreshold.
