@yildizpay/http-adapter 1.0.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -3
- package/README.tr.md +149 -0
- package/dist/contracts/http-client.contract.d.ts +26 -0
- package/dist/contracts/http-client.contract.js +20 -0
- package/dist/contracts/http-client.contract.js.map +1 -0
- package/dist/core/default-http-client.d.ts +5 -1
- package/dist/core/default-http-client.js +55 -3
- package/dist/core/default-http-client.js.map +1 -1
- package/dist/core/http.adapter.d.ts +5 -3
- package/dist/core/http.adapter.js +16 -9
- package/dist/core/http.adapter.js.map +1 -1
- package/dist/exceptions/circuit-breaker-open.exception.d.ts +4 -0
- package/dist/exceptions/circuit-breaker-open.exception.js +13 -0
- package/dist/exceptions/circuit-breaker-open.exception.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/resilience/circuit-breaker/circuit-breaker-options.d.ts +6 -0
- package/dist/resilience/circuit-breaker/circuit-breaker-options.js +3 -0
- package/dist/resilience/circuit-breaker/circuit-breaker-options.js.map +1 -0
- package/dist/resilience/circuit-breaker/circuit-breaker.d.ts +18 -0
- package/dist/resilience/circuit-breaker/circuit-breaker.js +83 -0
- package/dist/resilience/circuit-breaker/circuit-breaker.js.map +1 -0
- package/dist/resilience/circuit-breaker/circuit-state.enum.d.ts +5 -0
- package/dist/resilience/circuit-breaker/circuit-state.enum.js +10 -0
- package/dist/resilience/circuit-breaker/circuit-state.enum.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -5
package/README.md
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
# @yildizpay/http-adapter
|
|
2
2
|
|
|
3
|
+
**🇬🇧 English** | [🇹🇷 Türkçe](README.tr.md)
|
|
4
|
+
|
|
3
5
|

|
|
4
6
|

|
|
5
7
|

|
|
6
8
|
|
|
7
|
-
A professional, robust, and highly configurable HTTP client adapter designed for enterprise-grade Node.js applications. It provides a fluent API, built-in resilience patterns, and a powerful interceptor system, all sitting on top of the
|
|
9
|
+
A professional, robust, and highly configurable HTTP client adapter designed for enterprise-grade Node.js applications. It provides a fluent API, built-in resilience patterns, and a powerful interceptor system, all natively sitting on top of the **Node.js Native Fetch API**, making it a zero-dependency library while allowing injection of custom HTTP clients.
|
|
8
10
|
|
|
9
11
|
## Key Features
|
|
10
12
|
|
|
11
13
|
- **Fluent Request Builder:** Construct complex HTTP requests with an intuitive, chainable API.
|
|
12
14
|
- **Interceptor Architecture:** Easily implement middleware for logging, authentication, error handling, and data transformation.
|
|
13
|
-
- **Resilience & Reliability:** Built-in support for retry policies
|
|
15
|
+
- **Resilience & Reliability:** Built-in support for retry policies (Exponential Backoff, etc.) and a generic **Circuit Breaker** to handle transient failures gracefully and prevent cascading failures in S2S communication.
|
|
14
16
|
- **Type Safety:** Fully typed requests and responses using generics, ensuring type safety across your application.
|
|
15
17
|
- **Testable:** Designed with dependency injection in mind, making it easy to mock and test.
|
|
16
18
|
- **Immutable Design:** Core components are immutable to prevent side effects in concurrent environments.
|
|
@@ -47,13 +49,20 @@ const request = new RequestBuilder('https://api.example.com')
|
|
|
47
49
|
Instantiate the `HttpAdapter` with optional interceptors and retry policies.
|
|
48
50
|
|
|
49
51
|
```typescript
|
|
50
|
-
import { HttpAdapter, RetryPolicies } from '@yildizpay/http-adapter';
|
|
52
|
+
import { HttpAdapter, RetryPolicies, CircuitBreaker } from '@yildizpay/http-adapter';
|
|
53
|
+
|
|
54
|
+
const circuitBreaker = new CircuitBreaker({
|
|
55
|
+
failureThreshold: 5,
|
|
56
|
+
resetTimeoutMs: 60000,
|
|
57
|
+
});
|
|
51
58
|
|
|
52
59
|
const adapter = HttpAdapter.create(
|
|
53
60
|
[
|
|
54
61
|
/* interceptors */
|
|
55
62
|
],
|
|
56
63
|
RetryPolicies.exponential(3), // Retry up to 3 times with exponential backoff
|
|
64
|
+
undefined, // Optional custom HTTP client
|
|
65
|
+
circuitBreaker // Optional Circuit Breaker
|
|
57
66
|
);
|
|
58
67
|
```
|
|
59
68
|
|
|
@@ -90,6 +99,20 @@ import { RetryPolicies } from '@yildizpay/http-adapter';
|
|
|
90
99
|
const retryPolicy = RetryPolicies.exponential(5);
|
|
91
100
|
```
|
|
92
101
|
|
|
102
|
+
### Circuit Breaker
|
|
103
|
+
|
|
104
|
+
To protect your system from waiting for a completely down downstream service, you can employ the `CircuitBreaker`. It opens the circuit after a configured amount of consecutive failures and replies instantaneously with `CircuitBreakerOpenException` without hitting the unresponsive server.
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import { CircuitBreaker } from '@yildizpay/http-adapter';
|
|
108
|
+
|
|
109
|
+
const breaker = new CircuitBreaker({
|
|
110
|
+
failureThreshold: 5, // Trip after 5 failures
|
|
111
|
+
resetTimeoutMs: 30000, // Try a 'half-open' request after 30 seconds
|
|
112
|
+
successThreshold: 1, // Close circuit after 1 successful half-open request
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
93
116
|
## Interceptors
|
|
94
117
|
|
|
95
118
|
Interceptors allow you to hook into the lifecycle of a request. Implement the `HttpInterceptor` interface to create custom logic.
|
package/README.tr.md
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# @yildizpay/http-adapter
|
|
2
|
+
|
|
3
|
+
[🇬🇧 English](README.md) | 🇹🇷 **Türkçe**
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
Node.js tabanlı kurumsal seviye (enterprise-grade) uygulamalar için tasarlanmış profesyonel, dayanıklı (robust) ve yüksek oranda yapılandırılabilir bir HTTP istemci (client) adaptörü. Akıcı (fluent) bir API, yerleşik ağ direnci (resilience) desenleri ve güçlü bir önleyici (interceptor) sistemi sunar. Dış bağımlılık bulundurmayan (zero-dependency) paketin çekirdeği **Node.js Native Fetch API** kullanır ancak tercih edilen farklı özel HTTP istemcilerine de (Custom Clients) kolayca genişletilebilir.
|
|
10
|
+
|
|
11
|
+
## Temel Özellikler
|
|
12
|
+
|
|
13
|
+
- **Akıcı İstek Oluşturucu (Fluent Request Builder):** Sezgisel ve zincirlenebilir (chainable) bir API ile karmaşık HTTP isteklerini kolayca oluşturun.
|
|
14
|
+
- **Önleyici Mimarisi (Interceptor Architecture):** Loglama, kimlik doğrulama, hata yönetimi ve veri dönüşümü gibi ara yazılım (middleware) işlemlerini zahmetsizce entegre edin.
|
|
15
|
+
- **Ağ Direnci ve Güvenilirlik (Resilience & Reliability):** Sunucular arası entegrasyonlarda geçici arızaları zarif bir şekilde yönetmek ve zincirleme (cascading) hataları önlemek için üstel geri çekilme (Exponential Backoff vs.) gibi yeniden deneme (retry) politikaları ve yerleşik bir **Devre Kesici (Circuit Breaker)** içerir.
|
|
16
|
+
- **Tip Güvenliği (Type Safety):** Jenerikleri (generics) kullanan tam tiplendirilmiş (fully typed) istek ve yanıtlar ile uygulamanız genelinde tip güvenliği sağlar.
|
|
17
|
+
- **Test Edilebilirlik:** Bağımlılık enjeksiyonu (dependency injection) düşünülerek tasarlandığından, birim testleri (unit mock) yazmak oldukça kolaydır.
|
|
18
|
+
- **Değişmez (Immutable) Tasarım:** Eşzamanlı (concurrent) ortamlarda yan etkileri (side effects) önlemek için çekirdek (core) bileşenler değiştirilemez (immutable) yapıda tasarlanmıştır.
|
|
19
|
+
|
|
20
|
+
## Kurulum
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install @yildizpay/http-adapter
|
|
24
|
+
# veya
|
|
25
|
+
yarn add @yildizpay/http-adapter
|
|
26
|
+
# veya
|
|
27
|
+
pnpm add @yildizpay/http-adapter
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Kullanım
|
|
31
|
+
|
|
32
|
+
### 1. Temel İstek Oluşturma
|
|
33
|
+
|
|
34
|
+
İstekleri temiz ve öz bir şekilde oluşturmak için `RequestBuilder` sınıfını kullanın.
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { RequestBuilder, HttpMethod } from '@yildizpay/http-adapter';
|
|
38
|
+
|
|
39
|
+
const request = new RequestBuilder('https://api.example.com')
|
|
40
|
+
.setEndpoint('/users')
|
|
41
|
+
.setMethod(HttpMethod.POST)
|
|
42
|
+
.addHeader('Authorization', 'Bearer token')
|
|
43
|
+
.setBody({ name: 'Ahmet Yılmaz', email: 'ahmet@example.com' })
|
|
44
|
+
.build();
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 2. Adaptörü Başlatma
|
|
48
|
+
|
|
49
|
+
İsteğe bağlı önleyiciler (interceptors), yeniden deneme (retry) politikaları ve devre kesici (circuit breaker) ile `HttpAdapter` nesnesini oluşturun.
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { HttpAdapter, RetryPolicies, CircuitBreaker } from '@yildizpay/http-adapter';
|
|
53
|
+
|
|
54
|
+
const circuitBreaker = new CircuitBreaker({
|
|
55
|
+
failureThreshold: 5,
|
|
56
|
+
resetTimeoutMs: 60000,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const adapter = HttpAdapter.create(
|
|
60
|
+
[
|
|
61
|
+
/* interceptors (önleyiciler) */
|
|
62
|
+
],
|
|
63
|
+
RetryPolicies.exponential(3), // Üstel (exponential) geri çekilme ile 3 defaya kadar yeniden dene
|
|
64
|
+
undefined, // İsteğe bağlı özel HTTP istemcisi (opsiyonel)
|
|
65
|
+
circuitBreaker // İsteğe bağlı Devre Kesici (opsiyonel)
|
|
66
|
+
);
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 3. İstek Gönderme
|
|
70
|
+
|
|
71
|
+
İsteği yürütün ve kesin bir şekilde tiplendirilmiş (strongly-typed) yanıtı (response) alın.
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
interface UserResponse {
|
|
75
|
+
id: string;
|
|
76
|
+
name: string;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
const response = await adapter.send<UserResponse>(request);
|
|
81
|
+
console.log('Kullanıcı oluşturuldu:', response.data);
|
|
82
|
+
} catch (error) {
|
|
83
|
+
console.error('İstek başarısız oldu:', error);
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Direnç ve Yeniden Denemeler (Resilience & Retries)
|
|
88
|
+
|
|
89
|
+
Ağ kararsızlığı kaçınılmazdır. Bu adaptör, sağlam yeniden deneme stratejileri tanımlamanıza olanak tanır.
|
|
90
|
+
|
|
91
|
+
### Üstel Geri Çekilme (Exponential Backoff)
|
|
92
|
+
|
|
93
|
+
Yerleşik `ExponentialBackoffPolicy`, denemeler arasında giderek daha uzun süreler (ör. 200ms, 400ms, 800ms) bekler ve "gürleyen sürü" (thundering herd) sorunlarını önlemek için gecikmelere rastgele bir sapma (jitter) ekler.
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
import { RetryPolicies } from '@yildizpay/http-adapter';
|
|
97
|
+
|
|
98
|
+
// 429, 500, 502, 503, 504 durum kodlarında ve ağ hatalarında yeniden dener
|
|
99
|
+
const retryPolicy = RetryPolicies.exponential(5);
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Devre Kesici (Circuit Breaker)
|
|
103
|
+
|
|
104
|
+
Sisteminizi tamamen çökmüş olan bir sunucuyu beklemekten korumak için `CircuitBreaker` (Devre Kesici) yönteminden yararlanabilirsiniz. Konfigürasyonla belirlenmiş miktarda ardışık hata alındığında devre açılır ve yanıt vermeyen sunucuya gereksiz istek göndermeksizin anında `CircuitBreakerOpenException` fırlatarak cevap verir.
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import { CircuitBreaker } from '@yildizpay/http-adapter';
|
|
108
|
+
|
|
109
|
+
const breaker = new CircuitBreaker({
|
|
110
|
+
failureThreshold: 5, // 5 hatadan sonra devreyi aç
|
|
111
|
+
resetTimeoutMs: 30000, // 30 saniye sonra 'yarı-açık' (half-open) test isteği dene
|
|
112
|
+
successThreshold: 1, // Yarı-açık durumda 1 başarılı istek sonrası devreyi kapat
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Önleyiciler (Interceptors)
|
|
117
|
+
|
|
118
|
+
Önleyiciler (Interceptors), bir isteğin yaşam döngüsüne (lifecycle) dâhil olmanızı sağlar. Özel iş mantıkları kurgulamak için `HttpInterceptor` arayüzünü uygulamanız yeterlidir.
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
import { HttpInterceptor, Request, Response } from '@yildizpay/http-adapter';
|
|
122
|
+
|
|
123
|
+
export class LoggingInterceptor implements HttpInterceptor {
|
|
124
|
+
async onRequest(request: Request): Promise<Request> {
|
|
125
|
+
console.log(
|
|
126
|
+
`[${request.systemCorrelationId}] ${request.method} isteği ${request.endpoint} adresine gönderiliyor.`,
|
|
127
|
+
);
|
|
128
|
+
return request;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async onResponse(response: Response): Promise<Response> {
|
|
132
|
+
console.log(`İstek başarı durumu: ${response.status}`);
|
|
133
|
+
return response;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async onError(error: unknown, request: Request): Promise<unknown> {
|
|
137
|
+
console.error(`${request.endpoint} uç noktasına yapılan istekte hata oluştu`, error);
|
|
138
|
+
return error;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Katkıda Bulunma
|
|
144
|
+
|
|
145
|
+
Katkılarınızı her zaman bekliyoruz! Lütfen bir "Pull Request" göndermekten çekinmeyin.
|
|
146
|
+
|
|
147
|
+
## Lisans
|
|
148
|
+
|
|
149
|
+
Bu proje MIT Lisansı altında lisanslanmıştır.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { HttpMethod } from '../common/enums/http-method.enum';
|
|
2
|
+
import { HttpBody } from '../common/types/http.types';
|
|
3
|
+
export interface HttpClientRequestConfig {
|
|
4
|
+
url: string;
|
|
5
|
+
method: HttpMethod;
|
|
6
|
+
headers?: Record<string, string>;
|
|
7
|
+
data?: HttpBody | null;
|
|
8
|
+
timeout?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface HttpClientResponse<T = unknown> {
|
|
11
|
+
data: T;
|
|
12
|
+
status: number;
|
|
13
|
+
headers: Record<string, string>;
|
|
14
|
+
}
|
|
15
|
+
export interface HttpClientContract {
|
|
16
|
+
request<T = unknown>(config: HttpClientRequestConfig): Promise<HttpClientResponse<T>>;
|
|
17
|
+
}
|
|
18
|
+
export declare class HttpClientException<T = unknown> extends Error {
|
|
19
|
+
readonly response?: {
|
|
20
|
+
status: number;
|
|
21
|
+
data: T;
|
|
22
|
+
headers: Record<string, string>;
|
|
23
|
+
};
|
|
24
|
+
readonly code?: string;
|
|
25
|
+
constructor(message: string, status?: number, data?: T, headers?: Record<string, string>, code?: string);
|
|
26
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HttpClientException = void 0;
|
|
4
|
+
class HttpClientException extends Error {
|
|
5
|
+
constructor(message, status, data, headers, code) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = 'HttpClientException';
|
|
8
|
+
Object.setPrototypeOf(this, HttpClientException.prototype);
|
|
9
|
+
if (status !== undefined) {
|
|
10
|
+
this.response = {
|
|
11
|
+
status,
|
|
12
|
+
data: data,
|
|
13
|
+
headers: headers ?? {},
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
this.code = code;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.HttpClientException = HttpClientException;
|
|
20
|
+
//# sourceMappingURL=http-client.contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-client.contract.js","sourceRoot":"","sources":["../../src/contracts/http-client.contract.ts"],"names":[],"mappings":";;;AAkCA,MAAa,mBAAiC,SAAQ,KAAK;IAQzD,YACE,OAAe,EACf,MAAe,EACf,IAAQ,EACR,OAAgC,EAChC,IAAa;QAEb,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAC;QAE3D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,CAAC,QAAQ,GAAG;gBACd,MAAM;gBACN,IAAI,EAAE,IAAS;gBACf,OAAO,EAAE,OAAO,IAAI,EAAE;aACvB,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AA5BD,kDA4BC"}
|
|
@@ -1 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import { HttpClientContract, HttpClientRequestConfig, HttpClientResponse } from '../contracts/http-client.contract';
|
|
2
|
+
export declare class FetchHttpClient implements HttpClientContract {
|
|
3
|
+
request<T = unknown>(config: HttpClientRequestConfig): Promise<HttpClientResponse<T>>;
|
|
4
|
+
}
|
|
5
|
+
export declare const defaultHttpClient: FetchHttpClient;
|
|
@@ -1,6 +1,58 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.defaultHttpClient = void 0;
|
|
4
|
-
const
|
|
5
|
-
|
|
3
|
+
exports.defaultHttpClient = exports.FetchHttpClient = void 0;
|
|
4
|
+
const http_client_contract_1 = require("../contracts/http-client.contract");
|
|
5
|
+
class FetchHttpClient {
|
|
6
|
+
async request(config) {
|
|
7
|
+
const controller = new AbortController();
|
|
8
|
+
let timeoutId;
|
|
9
|
+
if (config.timeout && config.timeout > 0) {
|
|
10
|
+
timeoutId = setTimeout(() => controller.abort(), config.timeout);
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
const response = await fetch(config.url, {
|
|
14
|
+
method: config.method,
|
|
15
|
+
headers: {
|
|
16
|
+
'Content-Type': 'application/json',
|
|
17
|
+
...config.headers,
|
|
18
|
+
},
|
|
19
|
+
body: config.data ? JSON.stringify(config.data) : undefined,
|
|
20
|
+
signal: controller.signal,
|
|
21
|
+
});
|
|
22
|
+
let responseData = null;
|
|
23
|
+
const contentType = response.headers.get('content-type');
|
|
24
|
+
if (contentType?.includes('application/json')) {
|
|
25
|
+
responseData = await response.json().catch(() => null);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
responseData = await response.text().catch(() => null);
|
|
29
|
+
}
|
|
30
|
+
const responseHeaders = {};
|
|
31
|
+
response.headers.forEach((value, key) => {
|
|
32
|
+
responseHeaders[key] = value;
|
|
33
|
+
});
|
|
34
|
+
if (!response.ok) {
|
|
35
|
+
throw new http_client_contract_1.HttpClientException(`Request failed with status ${response.status}`, response.status, responseData, responseHeaders);
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
data: responseData,
|
|
39
|
+
status: response.status,
|
|
40
|
+
headers: responseHeaders,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
45
|
+
throw new http_client_contract_1.HttpClientException('Request Timeout', undefined, undefined, undefined, 'ECONNABORTED');
|
|
46
|
+
}
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
if (timeoutId) {
|
|
51
|
+
clearTimeout(timeoutId);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.FetchHttpClient = FetchHttpClient;
|
|
57
|
+
exports.defaultHttpClient = new FetchHttpClient();
|
|
6
58
|
//# sourceMappingURL=default-http-client.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-http-client.js","sourceRoot":"","sources":["../../src/core/default-http-client.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"default-http-client.js","sourceRoot":"","sources":["../../src/core/default-http-client.ts"],"names":[],"mappings":";;;AAAA,4EAK2C;AAQ3C,MAAa,eAAe;IACnB,KAAK,CAAC,OAAO,CAClB,MAA+B;QAE/B,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,IAAI,SAAqC,CAAC;QAE1C,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;YACzC,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QACnE,CAAC;QAED,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE;gBACvC,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,GAAG,MAAM,CAAC,OAAO;iBAClB;gBACD,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;gBAC3D,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;YAEH,IAAI,YAAY,GAAY,IAAI,CAAC;YACjC,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAEzD,IAAI,WAAW,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;gBAC9C,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;YACzD,CAAC;iBAAM,CAAC;gBACN,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;YACzD,CAAC;YAED,MAAM,eAAe,GAA2B,EAAE,CAAC;YACnD,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;gBACtC,eAAe,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YAC/B,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,0CAAmB,CAC3B,8BAA8B,QAAQ,CAAC,MAAM,EAAE,EAC/C,QAAQ,CAAC,MAAM,EACf,YAAiB,EACjB,eAAe,CAChB,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,IAAI,EAAE,YAAiB;gBACvB,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,OAAO,EAAE,eAAe;aACzB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC1D,MAAM,IAAI,0CAAmB,CAC3B,iBAAiB,EACjB,SAAS,EACT,SAAS,EACT,SAAS,EACT,cAAc,CACf,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;gBAAS,CAAC;YACT,IAAI,SAAS,EAAE,CAAC;gBACd,YAAY,CAAC,SAAS,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;IACH,CAAC;CACF;AAnED,0CAmEC;AAEY,QAAA,iBAAiB,GAAG,IAAI,eAAe,EAAE,CAAC"}
|
|
@@ -2,13 +2,15 @@ import { Request } from '../models/request';
|
|
|
2
2
|
import { Response } from '../models/response';
|
|
3
3
|
import { HttpInterceptor } from '../contracts/http-interceptor.contract';
|
|
4
4
|
import { RetryPolicy } from '../contracts/retry-policy.contract';
|
|
5
|
-
import {
|
|
5
|
+
import { CircuitBreaker } from '../resilience/circuit-breaker/circuit-breaker';
|
|
6
|
+
import { HttpClientContract } from '../contracts/http-client.contract';
|
|
6
7
|
export declare class HttpAdapter {
|
|
7
8
|
private readonly interceptors;
|
|
8
9
|
private readonly httpClient;
|
|
9
10
|
private readonly retryPolicy?;
|
|
11
|
+
private readonly circuitBreaker?;
|
|
10
12
|
private constructor();
|
|
11
|
-
static create(interceptors: HttpInterceptor[], retryPolicy?: RetryPolicy, httpClient?:
|
|
12
|
-
send<T =
|
|
13
|
+
static create(interceptors: HttpInterceptor[], retryPolicy?: RetryPolicy, httpClient?: HttpClientContract, circuitBreaker?: CircuitBreaker): HttpAdapter;
|
|
14
|
+
send<T = unknown>(request: Request): Promise<Response<T>>;
|
|
13
15
|
private dispatch;
|
|
14
16
|
}
|
|
@@ -5,20 +5,27 @@ const default_http_client_1 = require("./default-http-client");
|
|
|
5
5
|
const response_1 = require("../models/response");
|
|
6
6
|
const retry_executor_1 = require("../resilience/retry-executor");
|
|
7
7
|
class HttpAdapter {
|
|
8
|
-
constructor(interceptors, httpClient, retryPolicy) {
|
|
8
|
+
constructor(interceptors, httpClient, retryPolicy, circuitBreaker) {
|
|
9
9
|
this.interceptors = interceptors;
|
|
10
10
|
this.httpClient = httpClient;
|
|
11
11
|
this.retryPolicy = retryPolicy;
|
|
12
|
+
this.circuitBreaker = circuitBreaker;
|
|
12
13
|
}
|
|
13
|
-
static create(interceptors, retryPolicy, httpClient) {
|
|
14
|
-
return new HttpAdapter(interceptors, httpClient ?? default_http_client_1.defaultHttpClient, retryPolicy);
|
|
14
|
+
static create(interceptors, retryPolicy, httpClient, circuitBreaker) {
|
|
15
|
+
return new HttpAdapter(interceptors, httpClient ?? default_http_client_1.defaultHttpClient, retryPolicy, circuitBreaker);
|
|
15
16
|
}
|
|
16
17
|
async send(request) {
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
const executePipeline = () => {
|
|
19
|
+
if (!this.retryPolicy) {
|
|
20
|
+
return this.dispatch(request);
|
|
21
|
+
}
|
|
22
|
+
const executor = new retry_executor_1.RetryExecutor(this.retryPolicy);
|
|
23
|
+
return executor.execute(() => this.dispatch(request));
|
|
24
|
+
};
|
|
25
|
+
if (!this.circuitBreaker) {
|
|
26
|
+
return executePipeline();
|
|
19
27
|
}
|
|
20
|
-
|
|
21
|
-
return executor.execute(() => this.dispatch(request));
|
|
28
|
+
return this.circuitBreaker.execute(executePipeline);
|
|
22
29
|
}
|
|
23
30
|
async dispatch(request) {
|
|
24
31
|
let processedRequest = request;
|
|
@@ -32,14 +39,14 @@ class HttpAdapter {
|
|
|
32
39
|
url.search = searchParams.toString();
|
|
33
40
|
}
|
|
34
41
|
processedRequest.setTimestamp(new Date());
|
|
35
|
-
const
|
|
42
|
+
const clientResponse = await this.httpClient.request({
|
|
36
43
|
url: url.toString(),
|
|
37
44
|
method: processedRequest.method,
|
|
38
45
|
data: processedRequest.body,
|
|
39
46
|
headers: processedRequest.headers,
|
|
40
47
|
timeout: processedRequest.options?.timeout,
|
|
41
48
|
});
|
|
42
|
-
let response = response_1.Response.create(
|
|
49
|
+
let response = response_1.Response.create(clientResponse.data, clientResponse.status, clientResponse.headers ?? null, processedRequest.systemCorrelationId);
|
|
43
50
|
for (const interceptor of this.interceptors) {
|
|
44
51
|
response = await interceptor.onResponse(response);
|
|
45
52
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.adapter.js","sourceRoot":"","sources":["../../src/core/http.adapter.ts"],"names":[],"mappings":";;;AAAA,+DAA0D;AAE1D,iDAA8C;AAG9C,iEAA6D;
|
|
1
|
+
{"version":3,"file":"http.adapter.js","sourceRoot":"","sources":["../../src/core/http.adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CircuitBreakerOpenException = void 0;
|
|
4
|
+
const http_exception_1 = require("./http.exception");
|
|
5
|
+
class CircuitBreakerOpenException extends http_exception_1.HttpException {
|
|
6
|
+
constructor(message = 'Circuit Breaker is OPEN. Execution denied.') {
|
|
7
|
+
super(message, null);
|
|
8
|
+
this.name = 'CircuitBreakerOpenException';
|
|
9
|
+
Object.setPrototypeOf(this, CircuitBreakerOpenException.prototype);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.CircuitBreakerOpenException = CircuitBreakerOpenException;
|
|
13
|
+
//# sourceMappingURL=circuit-breaker-open.exception.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circuit-breaker-open.exception.js","sourceRoot":"","sources":["../../src/exceptions/circuit-breaker-open.exception.ts"],"names":[],"mappings":";;;AAAA,qDAAiD;AAKjD,MAAa,2BAA4B,SAAQ,8BAAa;IAC5D,YAAY,UAAkB,4CAA4C;QACxE,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,6BAA6B,CAAC;QAC1C,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,2BAA2B,CAAC,SAAS,CAAC,CAAC;IACrE,CAAC;CACF;AAND,kEAMC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,10 @@ export * from './models/request-options';
|
|
|
7
7
|
export * from './contracts/http-interceptor.contract';
|
|
8
8
|
export * from './contracts/retry-policy.contract';
|
|
9
9
|
export * from './resilience/retry.policies';
|
|
10
|
+
export * from './resilience/circuit-breaker/circuit-state.enum';
|
|
11
|
+
export * from './resilience/circuit-breaker/circuit-breaker-options';
|
|
12
|
+
export * from './resilience/circuit-breaker/circuit-breaker';
|
|
10
13
|
export * from './common/enums/http-method.enum';
|
|
11
14
|
export * from './common/types/http.types';
|
|
12
15
|
export * from './exceptions/http.exception';
|
|
16
|
+
export * from './exceptions/circuit-breaker-open.exception';
|
package/dist/index.js
CHANGED
|
@@ -23,7 +23,11 @@ __exportStar(require("./models/request-options"), exports);
|
|
|
23
23
|
__exportStar(require("./contracts/http-interceptor.contract"), exports);
|
|
24
24
|
__exportStar(require("./contracts/retry-policy.contract"), exports);
|
|
25
25
|
__exportStar(require("./resilience/retry.policies"), exports);
|
|
26
|
+
__exportStar(require("./resilience/circuit-breaker/circuit-state.enum"), exports);
|
|
27
|
+
__exportStar(require("./resilience/circuit-breaker/circuit-breaker-options"), exports);
|
|
28
|
+
__exportStar(require("./resilience/circuit-breaker/circuit-breaker"), exports);
|
|
26
29
|
__exportStar(require("./common/enums/http-method.enum"), exports);
|
|
27
30
|
__exportStar(require("./common/types/http.types"), exports);
|
|
28
31
|
__exportStar(require("./exceptions/http.exception"), exports);
|
|
32
|
+
__exportStar(require("./exceptions/circuit-breaker-open.exception"), exports);
|
|
29
33
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AACA,sDAAoC;AACpC,6DAA2C;AAG3C,6DAA2C;AAG3C,mDAAiC;AACjC,oDAAkC;AAClC,2DAAyC;AAGzC,wEAAsD;AACtD,oEAAkD;AAGlD,8DAA4C;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AACA,sDAAoC;AACpC,6DAA2C;AAG3C,6DAA2C;AAG3C,mDAAiC;AACjC,oDAAkC;AAClC,2DAAyC;AAGzC,wEAAsD;AACtD,oEAAkD;AAGlD,8DAA4C;AAC5C,kFAAgE;AAChE,uFAAqE;AACrE,+EAA6D;AAG7D,kEAAgD;AAChD,4DAA0C;AAG1C,8DAA4C;AAC5C,8EAA4D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circuit-breaker-options.js","sourceRoot":"","sources":["../../../src/resilience/circuit-breaker/circuit-breaker-options.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { CircuitState } from './circuit-state.enum';
|
|
2
|
+
import { CircuitBreakerOptions } from './circuit-breaker-options';
|
|
3
|
+
export declare class CircuitBreaker {
|
|
4
|
+
private state;
|
|
5
|
+
private failureCount;
|
|
6
|
+
private successCount;
|
|
7
|
+
private nextAttemptAt;
|
|
8
|
+
private readonly failureThreshold;
|
|
9
|
+
private readonly resetTimeoutMs;
|
|
10
|
+
private readonly successThreshold;
|
|
11
|
+
private readonly isFailurePredicate;
|
|
12
|
+
constructor(options?: CircuitBreakerOptions);
|
|
13
|
+
getState(): CircuitState;
|
|
14
|
+
execute<T>(operation: () => Promise<T>): Promise<T>;
|
|
15
|
+
private recordSuccess;
|
|
16
|
+
private recordFailure;
|
|
17
|
+
private transitionTo;
|
|
18
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CircuitBreaker = void 0;
|
|
4
|
+
const circuit_state_enum_1 = require("./circuit-state.enum");
|
|
5
|
+
const circuit_breaker_open_exception_1 = require("../../exceptions/circuit-breaker-open.exception");
|
|
6
|
+
class CircuitBreaker {
|
|
7
|
+
constructor(options) {
|
|
8
|
+
this.state = circuit_state_enum_1.CircuitState.CLOSED;
|
|
9
|
+
this.failureCount = 0;
|
|
10
|
+
this.successCount = 0;
|
|
11
|
+
this.nextAttemptAt = 0;
|
|
12
|
+
this.failureThreshold = options?.failureThreshold ?? 5;
|
|
13
|
+
this.resetTimeoutMs = options?.resetTimeoutMs ?? 60000;
|
|
14
|
+
this.successThreshold = options?.successThreshold ?? 1;
|
|
15
|
+
this.isFailurePredicate = options?.isFailure ?? (() => true);
|
|
16
|
+
}
|
|
17
|
+
getState() {
|
|
18
|
+
if (this.state === circuit_state_enum_1.CircuitState.OPEN) {
|
|
19
|
+
if (Date.now() >= this.nextAttemptAt) {
|
|
20
|
+
this.transitionTo(circuit_state_enum_1.CircuitState.HALF_OPEN);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return this.state;
|
|
24
|
+
}
|
|
25
|
+
async execute(operation) {
|
|
26
|
+
const currentState = this.getState();
|
|
27
|
+
if (currentState === circuit_state_enum_1.CircuitState.OPEN) {
|
|
28
|
+
throw new circuit_breaker_open_exception_1.CircuitBreakerOpenException();
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const result = await operation();
|
|
32
|
+
this.recordSuccess();
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
if (this.isFailurePredicate(error)) {
|
|
37
|
+
this.recordFailure();
|
|
38
|
+
}
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
recordSuccess() {
|
|
43
|
+
if (this.state === circuit_state_enum_1.CircuitState.HALF_OPEN) {
|
|
44
|
+
this.successCount++;
|
|
45
|
+
if (this.successCount >= this.successThreshold) {
|
|
46
|
+
this.transitionTo(circuit_state_enum_1.CircuitState.CLOSED);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
this.failureCount = 0;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
recordFailure() {
|
|
54
|
+
if (this.state === circuit_state_enum_1.CircuitState.HALF_OPEN) {
|
|
55
|
+
this.transitionTo(circuit_state_enum_1.CircuitState.OPEN);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
this.failureCount++;
|
|
59
|
+
if (this.failureCount >= this.failureThreshold) {
|
|
60
|
+
this.transitionTo(circuit_state_enum_1.CircuitState.OPEN);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
transitionTo(newState) {
|
|
65
|
+
this.state = newState;
|
|
66
|
+
if (newState === circuit_state_enum_1.CircuitState.OPEN) {
|
|
67
|
+
this.failureCount = 0;
|
|
68
|
+
this.successCount = 0;
|
|
69
|
+
this.nextAttemptAt = Date.now() + this.resetTimeoutMs;
|
|
70
|
+
}
|
|
71
|
+
else if (newState === circuit_state_enum_1.CircuitState.HALF_OPEN) {
|
|
72
|
+
this.failureCount = 0;
|
|
73
|
+
this.successCount = 0;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
this.failureCount = 0;
|
|
77
|
+
this.successCount = 0;
|
|
78
|
+
this.nextAttemptAt = 0;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
exports.CircuitBreaker = CircuitBreaker;
|
|
83
|
+
//# sourceMappingURL=circuit-breaker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circuit-breaker.js","sourceRoot":"","sources":["../../../src/resilience/circuit-breaker/circuit-breaker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CircuitState = void 0;
|
|
4
|
+
var CircuitState;
|
|
5
|
+
(function (CircuitState) {
|
|
6
|
+
CircuitState["CLOSED"] = "CLOSED";
|
|
7
|
+
CircuitState["OPEN"] = "OPEN";
|
|
8
|
+
CircuitState["HALF_OPEN"] = "HALF_OPEN";
|
|
9
|
+
})(CircuitState || (exports.CircuitState = CircuitState = {}));
|
|
10
|
+
//# sourceMappingURL=circuit-state.enum.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circuit-state.enum.js","sourceRoot":"","sources":["../../../src/resilience/circuit-breaker/circuit-state.enum.ts"],"names":[],"mappings":";;;AAGA,IAAY,YAeX;AAfD,WAAY,YAAY;IAItB,iCAAiB,CAAA;IAKjB,6BAAa,CAAA;IAKb,uCAAuB,CAAA;AACzB,CAAC,EAfW,YAAY,4BAAZ,YAAY,QAevB"}
|