@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.
Files changed (28) hide show
  1. package/README.md +26 -3
  2. package/README.tr.md +149 -0
  3. package/dist/contracts/http-client.contract.d.ts +26 -0
  4. package/dist/contracts/http-client.contract.js +20 -0
  5. package/dist/contracts/http-client.contract.js.map +1 -0
  6. package/dist/core/default-http-client.d.ts +5 -1
  7. package/dist/core/default-http-client.js +55 -3
  8. package/dist/core/default-http-client.js.map +1 -1
  9. package/dist/core/http.adapter.d.ts +5 -3
  10. package/dist/core/http.adapter.js +16 -9
  11. package/dist/core/http.adapter.js.map +1 -1
  12. package/dist/exceptions/circuit-breaker-open.exception.d.ts +4 -0
  13. package/dist/exceptions/circuit-breaker-open.exception.js +13 -0
  14. package/dist/exceptions/circuit-breaker-open.exception.js.map +1 -0
  15. package/dist/index.d.ts +4 -0
  16. package/dist/index.js +4 -0
  17. package/dist/index.js.map +1 -1
  18. package/dist/resilience/circuit-breaker/circuit-breaker-options.d.ts +6 -0
  19. package/dist/resilience/circuit-breaker/circuit-breaker-options.js +3 -0
  20. package/dist/resilience/circuit-breaker/circuit-breaker-options.js.map +1 -0
  21. package/dist/resilience/circuit-breaker/circuit-breaker.d.ts +18 -0
  22. package/dist/resilience/circuit-breaker/circuit-breaker.js +83 -0
  23. package/dist/resilience/circuit-breaker/circuit-breaker.js.map +1 -0
  24. package/dist/resilience/circuit-breaker/circuit-state.enum.d.ts +5 -0
  25. package/dist/resilience/circuit-breaker/circuit-state.enum.js +10 -0
  26. package/dist/resilience/circuit-breaker/circuit-state.enum.js.map +1 -0
  27. package/dist/tsconfig.tsbuildinfo +1 -1
  28. 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
  ![Build Status](https://github.com/yildizpay/http-adapter/actions/workflows/ci.yml/badge.svg)
4
6
  ![NPM Version](https://img.shields.io/npm/v/@yildizpay/http-adapter)
5
7
  ![License](https://img.shields.io/npm/l/@yildizpay/http-adapter)
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 reliable Axios library.
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, including Exponential Backoff with Jitter, to handle transient failures gracefully.
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
+ ![Build Status](https://github.com/yildizpay/http-adapter/actions/workflows/ci.yml/badge.svg)
6
+ ![NPM Version](https://img.shields.io/npm/v/@yildizpay/http-adapter)
7
+ ![License](https://img.shields.io/npm/l/@yildizpay/http-adapter)
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
- export declare const defaultHttpClient: import("axios").AxiosInstance;
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 axios_1 = require("axios");
5
- exports.defaultHttpClient = axios_1.default.create();
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,iCAA0B;AASb,QAAA,iBAAiB,GAAG,eAAK,CAAC,MAAM,EAAE,CAAC"}
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 { AxiosInstance } from 'axios';
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?: AxiosInstance): HttpAdapter;
12
- send<T = any>(request: Request): Promise<Response<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
- if (!this.retryPolicy) {
18
- return this.dispatch(request);
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
- const executor = new retry_executor_1.RetryExecutor(this.retryPolicy);
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 axiosResponse = await this.httpClient.request({
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(axiosResponse.data, axiosResponse.status, axiosResponse.headers ?? null, processedRequest.systemCorrelationId);
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;AAa7D,MAAa,WAAW;IAQtB,YACmB,YAA+B,EAC/B,UAAyB,EACzB,WAAyB;QAFzB,iBAAY,GAAZ,YAAY,CAAmB;QAC/B,eAAU,GAAV,UAAU,CAAe;QACzB,gBAAW,GAAX,WAAW,CAAc;IACzC,CAAC;IAUG,MAAM,CAAC,MAAM,CAClB,YAA+B,EAC/B,WAAyB,EACzB,UAA0B;QAE1B,OAAO,IAAI,WAAW,CAAC,YAAY,EAAE,UAAU,IAAI,uCAAiB,EAAE,WAAW,CAAC,CAAC;IACrF,CAAC;IAUM,KAAK,CAAC,IAAI,CAAU,OAAgB;QACzC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC,QAAQ,CAAI,OAAO,CAAC,CAAC;QACnC,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,8BAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACrD,OAAO,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAI,OAAO,CAAC,CAAC,CAAC;IAC3D,CAAC;IAWO,KAAK,CAAC,QAAQ,CAAU,OAAgB;QAC9C,IAAI,gBAAgB,GAAY,OAAO,CAAC;QAGxC,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YAC5C,gBAAgB,GAAG,MAAM,WAAW,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QACnE,CAAC;QAED,IAAI,CAAC;YAEH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,QAAQ,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;YACzE,MAAM,YAAY,GAAG,IAAI,eAAe,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;YACvE,IAAI,YAAY,CAAC,QAAQ,EAAE,EAAE,CAAC;gBAC5B,GAAG,CAAC,MAAM,GAAG,YAAY,CAAC,QAAQ,EAAE,CAAC;YACvC,CAAC;YAED,gBAAgB,CAAC,YAAY,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;YAG1C,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;gBAClD,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE;gBACnB,MAAM,EAAE,gBAAgB,CAAC,MAAM;gBAC/B,IAAI,EAAE,gBAAgB,CAAC,IAAI;gBAC3B,OAAO,EAAE,gBAAgB,CAAC,OAAO;gBACjC,OAAO,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO;aAC3C,CAAC,CAAC;YAGH,IAAI,QAAQ,GAAG,mBAAQ,CAAC,MAAM,CAC5B,aAAa,CAAC,IAAI,EAClB,aAAa,CAAC,MAAM,EACnB,aAAa,CAAC,OAAkC,IAAI,IAAI,EACzD,gBAAgB,CAAC,mBAAmB,CACrC,CAAC;YAGF,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBAC5C,QAAQ,GAAG,MAAM,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YACpD,CAAC;YAED,OAAO,QAAQ,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,eAAe,GAAG,KAAK,CAAC;YAG5B,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBAC5C,eAAe,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC;YACjF,CAAC;YAED,MAAM,eAAe,CAAC;QACxB,CAAC;IACH,CAAC;CACF;AA5GD,kCA4GC"}
1
+ {"version":3,"file":"http.adapter.js","sourceRoot":"","sources":["../../src/core/http.adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { HttpException } from './http.exception';
2
+ export declare class CircuitBreakerOpenException extends HttpException {
3
+ constructor(message?: string);
4
+ }
@@ -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;AAG5C,kEAAgD;AAChD,4DAA0C;AAG1C,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,6 @@
1
+ export interface CircuitBreakerOptions {
2
+ failureThreshold?: number;
3
+ resetTimeoutMs?: number;
4
+ successThreshold?: number;
5
+ isFailure?: (error: unknown) => boolean;
6
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=circuit-breaker-options.js.map
@@ -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,5 @@
1
+ export declare enum CircuitState {
2
+ CLOSED = "CLOSED",
3
+ OPEN = "OPEN",
4
+ HALF_OPEN = "HALF_OPEN"
5
+ }
@@ -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"}