@yildizpay/http-adapter 3.0.0 → 3.2.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 +253 -9
- package/README.tr.md +288 -44
- package/dist/builders/request.builder.d.ts +3 -0
- package/dist/builders/request.builder.js +6 -1
- package/dist/builders/request.builder.js.map +1 -1
- package/dist/contracts/http-client.contract.d.ts +0 -9
- package/dist/contracts/http-client.contract.js +0 -17
- package/dist/contracts/http-client.contract.js.map +1 -1
- package/dist/contracts/http-interceptor.contract.d.ts +6 -2
- package/dist/contracts/response-validator.contract.d.ts +4 -0
- package/dist/contracts/response-validator.contract.js +3 -0
- package/dist/contracts/response-validator.contract.js.map +1 -0
- package/dist/core/default-http-client.js +7 -6
- package/dist/core/default-http-client.js.map +1 -1
- package/dist/core/error.converter.d.ts +5 -0
- package/dist/core/error.converter.js +31 -0
- package/dist/core/error.converter.js.map +1 -0
- package/dist/core/http.adapter.js +28 -4
- package/dist/core/http.adapter.js.map +1 -1
- package/dist/exceptions/base-adapter.exception.d.ts +7 -0
- package/dist/exceptions/base-adapter.exception.js +34 -0
- package/dist/exceptions/base-adapter.exception.js.map +1 -0
- package/dist/exceptions/circuit-breaker-open.exception.d.ts +2 -2
- package/dist/exceptions/circuit-breaker-open.exception.js +3 -3
- package/dist/exceptions/circuit-breaker-open.exception.js.map +1 -1
- package/dist/exceptions/exception.guards.d.ts +17 -0
- package/dist/exceptions/exception.guards.js +53 -0
- package/dist/exceptions/exception.guards.js.map +1 -0
- package/dist/exceptions/http-exception.factory.d.ts +5 -0
- package/dist/exceptions/http-exception.factory.js +59 -0
- package/dist/exceptions/http-exception.factory.js.map +1 -0
- package/dist/exceptions/http-status.exceptions.d.ts +134 -0
- package/dist/exceptions/http-status.exceptions.js +382 -0
- package/dist/exceptions/http-status.exceptions.js.map +1 -0
- package/dist/exceptions/network-exception.factory.d.ts +6 -0
- package/dist/exceptions/network-exception.factory.js +35 -0
- package/dist/exceptions/network-exception.factory.js.map +1 -0
- package/dist/exceptions/network.exceptions.d.ts +25 -0
- package/dist/exceptions/network.exceptions.js +69 -0
- package/dist/exceptions/network.exceptions.js.map +1 -0
- package/dist/exceptions/unknown.exception.d.ts +7 -0
- package/dist/exceptions/unknown.exception.js +20 -0
- package/dist/exceptions/unknown.exception.js.map +1 -0
- package/dist/exceptions/validation.exception.d.ts +9 -0
- package/dist/exceptions/validation.exception.js +25 -0
- package/dist/exceptions/validation.exception.js.map +1 -0
- package/dist/index.d.ts +11 -1
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/dist/models/request-context.d.ts +5 -0
- package/dist/models/request-context.js +3 -0
- package/dist/models/request-context.js.map +1 -0
- package/dist/models/request.d.ts +3 -1
- package/dist/models/request.js +2 -1
- package/dist/models/request.js.map +1 -1
- package/dist/models/response.d.ts +8 -5
- package/dist/models/response.js +9 -5
- package/dist/models/response.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +17 -3
- package/dist/exceptions/http.exception.d.ts +0 -5
- package/dist/exceptions/http.exception.js +0 -12
- package/dist/exceptions/http.exception.js.map +0 -1
package/README.tr.md
CHANGED
|
@@ -6,16 +6,18 @@
|
|
|
6
6
|

|
|
7
7
|

|
|
8
8
|
|
|
9
|
-
Node.js tabanlı kurumsal
|
|
9
|
+
Node.js tabanlı kurumsal uygulamalar için tasarlanmış profesyonel ve yüksek oranda yapılandırılabilir bir HTTP client adaptörü. Fluent API, built-in resilience pattern'ları, güçlü bir interceptor sistemi ve kapsamlı bir exception hiyerarşisi sunar. Zero-dependency olan paketin çekirdeği **Node.js Native Fetch API** kullanır; ancak istenen farklı custom HTTP client'lara da kolayca genişletilebilir.
|
|
10
10
|
|
|
11
11
|
## Temel Özellikler
|
|
12
12
|
|
|
13
|
-
- **
|
|
14
|
-
-
|
|
15
|
-
- **
|
|
16
|
-
- **
|
|
17
|
-
- **
|
|
18
|
-
- **
|
|
13
|
+
- **Fluent Request Builder:** Sezgisel ve zincirlenebilir bir API ile karmaşık HTTP isteklerini kolayca oluşturun.
|
|
14
|
+
- **Structured Exception Hierarchy:** Her HTTP durum kodu ve ağ hatası, zengin metadata, `isRetryable()` sinyali ve `toJSON()` desteğiyle ayrı bir exception sınıfına dönüştürülür.
|
|
15
|
+
- **Response Validation:** Herhangi bir request'e bir veya daha fazla `ResponseValidator` ekleyerek schema kısıtlamalarını veya business rule'ları response kodunuza ulaşmadan otomatik olarak denetleyebilirsiniz.
|
|
16
|
+
- **Interceptor Mimarisi:** Loglama, kimlik doğrulama, hata yönetimi ve veri dönüşümü gibi middleware işlemlerini zahmetsizce entegre edin.
|
|
17
|
+
- **Resilience & Reliability:** S2S entegrasyonlarında geçici hataları zarif bir şekilde yönetmek için Exponential Backoff gibi retry policy'ler ve built-in **Circuit Breaker** içerir.
|
|
18
|
+
- **Type Safety:** Generic'ler kullanılarak tam olarak tiplendirilmiş request ve response'lar ile uygulama genelinde tip güvenliği sağlanır.
|
|
19
|
+
- **Test Edilebilirlik:** Dependency injection düşünülerek tasarlandığından mock yazmak oldukça kolaydır.
|
|
20
|
+
- **Immutable Tasarım:** Concurrent ortamlarda side effect'leri önlemek için core bileşenler immutable olarak tasarlanmıştır.
|
|
19
21
|
|
|
20
22
|
## Kurulum
|
|
21
23
|
|
|
@@ -29,9 +31,9 @@ pnpm add @yildizpay/http-adapter
|
|
|
29
31
|
|
|
30
32
|
## Kullanım
|
|
31
33
|
|
|
32
|
-
### 1.
|
|
34
|
+
### 1. Request Oluşturma
|
|
33
35
|
|
|
34
|
-
|
|
36
|
+
`RequestBuilder` ile istekleri temiz ve öz bir şekilde oluşturun.
|
|
35
37
|
|
|
36
38
|
```typescript
|
|
37
39
|
import { RequestBuilder, HttpMethod } from '@yildizpay/http-adapter';
|
|
@@ -44,31 +46,31 @@ const request = new RequestBuilder('https://api.example.com')
|
|
|
44
46
|
.build();
|
|
45
47
|
```
|
|
46
48
|
|
|
47
|
-
### 2.
|
|
49
|
+
### 2. Adapter'ı Başlatma
|
|
48
50
|
|
|
49
|
-
İsteğe bağlı
|
|
51
|
+
İsteğe bağlı interceptor'lar, retry policy ve circuit breaker ile `HttpAdapter` oluşturun.
|
|
50
52
|
|
|
51
53
|
```typescript
|
|
52
54
|
import { HttpAdapter, RetryPolicies, CircuitBreaker } from '@yildizpay/http-adapter';
|
|
53
55
|
|
|
54
56
|
const circuitBreaker = new CircuitBreaker({
|
|
55
57
|
failureThreshold: 5,
|
|
56
|
-
resetTimeoutMs: 60000,
|
|
58
|
+
resetTimeoutMs: 60000,
|
|
57
59
|
});
|
|
58
60
|
|
|
59
61
|
const adapter = HttpAdapter.create(
|
|
60
62
|
[
|
|
61
|
-
/* interceptors
|
|
63
|
+
/* interceptors */
|
|
62
64
|
],
|
|
63
|
-
RetryPolicies.exponential(3), //
|
|
64
|
-
undefined, //
|
|
65
|
-
circuitBreaker
|
|
65
|
+
RetryPolicies.exponential(3), // Exponential backoff ile 3 defaya kadar retry
|
|
66
|
+
undefined, // Opsiyonel custom HTTP client
|
|
67
|
+
circuitBreaker, // Opsiyonel Circuit Breaker
|
|
66
68
|
);
|
|
67
69
|
```
|
|
68
70
|
|
|
69
|
-
### 3.
|
|
71
|
+
### 3. Request Gönderme
|
|
70
72
|
|
|
71
|
-
|
|
73
|
+
Request'i çalıştırın ve strongly-typed response alın.
|
|
72
74
|
|
|
73
75
|
```typescript
|
|
74
76
|
interface UserResponse {
|
|
@@ -80,45 +82,281 @@ try {
|
|
|
80
82
|
const response = await adapter.send<UserResponse>(request);
|
|
81
83
|
console.log('Kullanıcı oluşturuldu:', response.data);
|
|
82
84
|
} catch (error) {
|
|
83
|
-
console.error('
|
|
85
|
+
console.error('Request başarısız oldu:', error);
|
|
84
86
|
}
|
|
85
87
|
```
|
|
86
88
|
|
|
87
|
-
##
|
|
89
|
+
## Hata Yönetimi (Error Handling)
|
|
88
90
|
|
|
89
|
-
|
|
91
|
+
`@yildizpay/http-adapter`, her türlü ham hatayı — HTTP hataları, OS düzeyindeki ağ hataları veya tamamen beklenmedik exception'lar — yapılandırılmış ve tiplendirilmiş bir exception sınıfına dönüştürür. Bu sayede `catch` bloklarında ham durum kodlarını ya da hata kodlarını elle incelemenize gerek kalmaz.
|
|
90
92
|
|
|
91
|
-
###
|
|
93
|
+
### Exception Hiyerarşisi
|
|
92
94
|
|
|
93
|
-
|
|
95
|
+
```
|
|
96
|
+
BaseAdapterException
|
|
97
|
+
├── HttpException (herhangi bir HTTP response hatası)
|
|
98
|
+
│ ├── BadRequestException (400)
|
|
99
|
+
│ ├── UnauthorizedException (401)
|
|
100
|
+
│ ├── ForbiddenException (403)
|
|
101
|
+
│ ├── NotFoundException (404)
|
|
102
|
+
│ ├── ConflictException (409)
|
|
103
|
+
│ ├── UnprocessableEntityException (422)
|
|
104
|
+
│ ├── TooManyRequestsException (429) ← isRetryable() = true
|
|
105
|
+
│ ├── InternalServerErrorException (500)
|
|
106
|
+
│ ├── BadGatewayException (502) ← isRetryable() = true
|
|
107
|
+
│ ├── ServiceUnavailableException (503) ← isRetryable() = true
|
|
108
|
+
│ ├── GatewayTimeoutException (504) ← isRetryable() = true
|
|
109
|
+
│ └── ... (tüm 4xx / 5xx kodları)
|
|
110
|
+
├── NetworkException (OS düzeyindeki bağlantı hataları)
|
|
111
|
+
│ ├── ConnectionRefusedException (ECONNREFUSED) ← isRetryable() = true
|
|
112
|
+
│ ├── TimeoutException (ETIMEDOUT / ECONNABORTED / AbortError) ← isRetryable() = true
|
|
113
|
+
│ ├── SocketResetException (ECONNRESET) ← isRetryable() = true
|
|
114
|
+
│ ├── DnsResolutionException (ENOTFOUND / EAI_AGAIN)
|
|
115
|
+
│ └── HostUnreachableException (EHOSTUNREACH / ENETUNREACH)
|
|
116
|
+
├── UnknownException (sınıflandırılamayan her türlü hata)
|
|
117
|
+
└── CircuitBreakerOpenException (circuit açık, request gönderilmedi)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Exception Türüne Göre Yakalama
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
import {
|
|
124
|
+
NotFoundException,
|
|
125
|
+
TooManyRequestsException,
|
|
126
|
+
TimeoutException,
|
|
127
|
+
ConnectionRefusedException,
|
|
128
|
+
CircuitBreakerOpenException,
|
|
129
|
+
UnknownException,
|
|
130
|
+
} from '@yildizpay/http-adapter';
|
|
131
|
+
|
|
132
|
+
try {
|
|
133
|
+
const response = await adapter.send<PaymentResponse>(request);
|
|
134
|
+
} catch (error) {
|
|
135
|
+
if (error instanceof NotFoundException) {
|
|
136
|
+
// HTTP 404 — kaynak bulunamadı
|
|
137
|
+
console.error('Kaynak bulunamadı:', error.response.data);
|
|
138
|
+
} else if (error instanceof TooManyRequestsException) {
|
|
139
|
+
// HTTP 429 — retry'dan önce bekle
|
|
140
|
+
const retryAfterMs = error.getRetryAfterMs();
|
|
141
|
+
console.warn(`Rate limit aşıldı. ${retryAfterMs}ms sonra tekrar dene`);
|
|
142
|
+
} else if (error instanceof TimeoutException) {
|
|
143
|
+
// ETIMEDOUT / AbortError — downstream servis yavaş
|
|
144
|
+
console.error('Request timeout:', error.code);
|
|
145
|
+
} else if (error instanceof ConnectionRefusedException) {
|
|
146
|
+
// ECONNREFUSED — downstream servis kapalı
|
|
147
|
+
console.error('Servis kapalı:', error.requestContext?.url);
|
|
148
|
+
} else if (error instanceof CircuitBreakerOpenException) {
|
|
149
|
+
// Circuit açık — sunucuya istek gönderilmeden fail fast
|
|
150
|
+
console.error('Circuit breaker açık. Request gönderilmedi.');
|
|
151
|
+
} else if (error instanceof UnknownException) {
|
|
152
|
+
// Beklenmedik bir hata — logla ve araştır
|
|
153
|
+
console.error('Bilinmeyen hata:', error.toJSON());
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Type Guard'lar
|
|
159
|
+
|
|
160
|
+
`instanceof` kullanmadan type narrowing tercih ediyorsanız — fonksiyonel pipeline'larda veya modül sınırlarını geçerken kullanışlıdır — her exception sınıfının karşılık gelen bir type guard'ı mevcuttur:
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
import {
|
|
164
|
+
isHttpException,
|
|
165
|
+
isTimeoutException,
|
|
166
|
+
isConnectionRefusedException,
|
|
167
|
+
isCircuitBreakerOpenException,
|
|
168
|
+
} from '@yildizpay/http-adapter';
|
|
169
|
+
|
|
170
|
+
function handleError(error: unknown): void {
|
|
171
|
+
if (isTimeoutException(error)) {
|
|
172
|
+
// TypeScript artık biliyor: error, TimeoutException türünde
|
|
173
|
+
scheduleRetry(error.requestContext?.url);
|
|
174
|
+
} else if (isHttpException(error)) {
|
|
175
|
+
// TypeScript artık biliyor: error, HttpException türünde
|
|
176
|
+
reportToMonitoring(error.response.status, error.response.data);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### `isRetryable()` Sinyali
|
|
182
|
+
|
|
183
|
+
Her exception, hatanın geçici olup olmadığını ve retry'a değer olup olmadığını belirten bir `isRetryable(): boolean` metodu sunar. Custom retry decorator'lar yazarken ya da uygulama katmanında hatayı tekrar denemek isteyip istemediğinize karar verirken kullanışlıdır.
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
} catch (error) {
|
|
187
|
+
if (error instanceof BaseAdapterException && error.isRetryable()) {
|
|
188
|
+
return retryOperation();
|
|
189
|
+
}
|
|
190
|
+
throw error;
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Retry edilebilir exception'lar: `TooManyRequestsException (429)`, `BadGatewayException (502)`, `ServiceUnavailableException (503)`, `GatewayTimeoutException (504)`, `TimeoutException`, `SocketResetException`, `ConnectionRefusedException`.
|
|
195
|
+
|
|
196
|
+
### `toJSON()` ile Structured Logging
|
|
197
|
+
|
|
198
|
+
Tüm exception'lar `toJSON()` metodunu override eder; bu sayede Pino, Winston gibi structured logger'larla tam uyumludur. `JSON.stringify(error)` çağrısı boş `{}` yerine eksiksiz bir log objesi üretir.
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
} catch (error) {
|
|
202
|
+
if (error instanceof BaseAdapterException) {
|
|
203
|
+
logger.error(error.toJSON());
|
|
204
|
+
// {
|
|
205
|
+
// name: 'NotFoundException',
|
|
206
|
+
// message: 'Not Found',
|
|
207
|
+
// code: 'ERR_NOT_FOUND',
|
|
208
|
+
// stack: '...',
|
|
209
|
+
// response: {
|
|
210
|
+
// status: 404,
|
|
211
|
+
// data: { detail: 'Ödeme kaydı bulunamadı' },
|
|
212
|
+
// request: { method: 'GET', url: 'https://api.example.com/payments/123', correlationId: 'corr-abc' }
|
|
213
|
+
// }
|
|
214
|
+
// }
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### `RequestContext` — Güvenli Request Metadata
|
|
220
|
+
|
|
221
|
+
Her exception, kaynak request'ten alınan `RequestContext` objesini (`method`, `url`, `correlationId`) otomatik olarak taşır. Auth token'larının veya kişisel verilerin (PII) loglara sızmasını önlemek amacıyla header ve body bilgileri bu objeden kasıtlı olarak çıkarılmıştır.
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
} catch (error) {
|
|
225
|
+
if (error instanceof NetworkException) {
|
|
226
|
+
logger.warn({
|
|
227
|
+
event: 'network_failure',
|
|
228
|
+
exception: error.name,
|
|
229
|
+
request: error.requestContext, // { method, url, correlationId }
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Response Validator'lar
|
|
236
|
+
|
|
237
|
+
Request'e validator ekleyerek schema kısıtlamalarını veya business rule'ları response kodunuza ulaşmadan otomatik olarak denetleyebilirsiniz. Validator'lar HTTP çağrısı başarılı olduktan sonra, response-side interceptor'lardan önce sırayla çalışır. İlk hata veren validator chain'i durdurur.
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
import { ResponseValidator, ValidationException, Response } from '@yildizpay/http-adapter';
|
|
241
|
+
|
|
242
|
+
class PaymentStatusValidator implements ResponseValidator<IyzicoResponse> {
|
|
243
|
+
validate(response: Response<IyzicoResponse>): void {
|
|
244
|
+
if (response.data.status !== 'success') {
|
|
245
|
+
throw new ValidationException(
|
|
246
|
+
`Payment failed: ${response.data.errorMessage}`,
|
|
247
|
+
response,
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Zod, Joi gibi herhangi bir validation kütüphanesiyle çalışır
|
|
254
|
+
class PaymentSchemaValidator implements ResponseValidator<unknown> {
|
|
255
|
+
validate(response: Response<unknown>): void {
|
|
256
|
+
IyzicoResponseSchema.parse(response.data); // Zod uyuşmazlıkta exception fırlatır
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const request = new RequestBuilder('https://api.iyzipay.com')
|
|
261
|
+
.setEndpoint('/payment/auth')
|
|
262
|
+
.setMethod(HttpMethod.POST)
|
|
263
|
+
.setBody(dto)
|
|
264
|
+
.validateWith(new PaymentSchemaValidator(), new PaymentStatusValidator())
|
|
265
|
+
.build();
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Validation hatasını yakalamak:
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
import { isValidationException } from '@yildizpay/http-adapter';
|
|
272
|
+
|
|
273
|
+
} catch (error) {
|
|
274
|
+
if (isValidationException(error)) {
|
|
275
|
+
console.error('Validation başarısız:', error.message);
|
|
276
|
+
console.error('Ham response:', error.response.data);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Validator içinde fırlatılan `BaseAdapterException` olmayan hatalar (örn. `ZodError`) otomatik olarak `ValidationException`'a sarılır; orijinal hata `cause`'ta tutulur. Typed erişim için generic parametre kullanılabilir:
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
} catch (error) {
|
|
285
|
+
if (isValidationException<ZodError>(error) && error.cause) {
|
|
286
|
+
console.error('Schema hataları:', error.cause.issues);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Validator kayıtlıyken tam interceptor lifecycle'ı:
|
|
292
|
+
|
|
293
|
+
```
|
|
294
|
+
onRequest → HTTP call → onResponse → validators → onResponseValidated → caller
|
|
295
|
+
↓ (hata durumunda)
|
|
296
|
+
onError
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
`onResponse` her zaman çalışır. `onResponseValidated` yalnızca tüm validator'lar geçtiğinde çalışır — business açısından geçerli bir response gerektiren cache veya side effect işlemleri için idealdir.
|
|
300
|
+
|
|
301
|
+
### Error Interceptor
|
|
302
|
+
|
|
303
|
+
Exception'lar business logic'e ulaşmadan önce interceptor seviyesinde yakalanabilir ve dönüştürülebilir.
|
|
304
|
+
|
|
305
|
+
```typescript
|
|
306
|
+
import {
|
|
307
|
+
HttpErrorInterceptor,
|
|
308
|
+
Request,
|
|
309
|
+
BaseAdapterException,
|
|
310
|
+
UnauthorizedException,
|
|
311
|
+
} from '@yildizpay/http-adapter';
|
|
312
|
+
|
|
313
|
+
export class GlobalErrorInterceptor implements HttpErrorInterceptor {
|
|
314
|
+
async onError(error: BaseAdapterException, request: Request): Promise<never> {
|
|
315
|
+
if (error instanceof UnauthorizedException) {
|
|
316
|
+
await this.tokenService.refresh();
|
|
317
|
+
}
|
|
318
|
+
// Caller'ın handle edebilmesi için hatayı yeniden fırlat
|
|
319
|
+
throw error;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## Resilience & Retry
|
|
325
|
+
|
|
326
|
+
Ağ kararsızlığı kaçınılmazdır. Bu adaptör, sağlam retry stratejileri tanımlamanıza olanak tanır.
|
|
327
|
+
|
|
328
|
+
### Exponential Backoff
|
|
329
|
+
|
|
330
|
+
Built-in `ExponentialBackoffPolicy`, denemeler arasında giderek artan süreler (ör. 200ms, 400ms, 800ms) bekler ve "thundering herd" sorununu önlemek için gecikmelere rastgele jitter ekler.
|
|
94
331
|
|
|
95
332
|
```typescript
|
|
96
333
|
import { RetryPolicies } from '@yildizpay/http-adapter';
|
|
97
334
|
|
|
98
|
-
// 429,
|
|
335
|
+
// 429, 502, 503, 504 ve ağ hatalarında retry yapar
|
|
99
336
|
const retryPolicy = RetryPolicies.exponential(5);
|
|
100
337
|
```
|
|
101
338
|
|
|
102
|
-
###
|
|
339
|
+
### Circuit Breaker
|
|
103
340
|
|
|
104
|
-
|
|
341
|
+
Tamamen çökmüş bir downstream servisi beklemeye karşı sisteminizi korumak için `CircuitBreaker` kullanabilirsiniz. Belirli sayıda ardışık hata alındığında circuit açılır ve yanıt vermeyen servise gereksiz istek göndermeksizin anında `CircuitBreakerOpenException` fırlatır.
|
|
105
342
|
|
|
106
343
|
```typescript
|
|
107
344
|
import { CircuitBreaker } from '@yildizpay/http-adapter';
|
|
108
345
|
|
|
109
346
|
const breaker = new CircuitBreaker({
|
|
110
|
-
failureThreshold: 5, // 5 hatadan sonra
|
|
111
|
-
resetTimeoutMs: 30000, // 30 saniye sonra
|
|
112
|
-
successThreshold: 1, //
|
|
347
|
+
failureThreshold: 5, // 5 hatadan sonra circuit'i aç
|
|
348
|
+
resetTimeoutMs: 30000, // 30 saniye sonra half-open test isteği gönder
|
|
349
|
+
successThreshold: 1, // 1 başarılı half-open request sonrası circuit'i kapat
|
|
113
350
|
});
|
|
114
351
|
```
|
|
115
352
|
|
|
116
|
-
##
|
|
353
|
+
## Interceptors
|
|
354
|
+
|
|
355
|
+
**Interface Segregation Principle (ISP)** sayesinde gereksiz metodları implement etmek zorunda kalmazsınız. Yalnızca ihtiyaç duyduğunuz lifecycle event'e göre `HttpRequestInterceptor`, `HttpResponseInterceptor` veya `HttpErrorInterceptor` interface'ini implement edebilirsiniz.
|
|
117
356
|
|
|
118
|
-
|
|
357
|
+
### 1. Request Interceptor (Örn: Auth Token)
|
|
119
358
|
|
|
120
|
-
|
|
121
|
-
İstekler yola çıkmadan önce `Authorization` (Yetkilendirme) gibi başlıkları otomatik ekleyebilirsiniz.
|
|
359
|
+
Request'ler gönderilmeden önce `Authorization` gibi header'ları otomatik ekleyebilirsiniz.
|
|
122
360
|
|
|
123
361
|
```typescript
|
|
124
362
|
import { HttpRequestInterceptor, Request } from '@yildizpay/http-adapter';
|
|
@@ -131,8 +369,9 @@ export class AuthInterceptor implements HttpRequestInterceptor {
|
|
|
131
369
|
}
|
|
132
370
|
```
|
|
133
371
|
|
|
134
|
-
### 2.
|
|
135
|
-
|
|
372
|
+
### 2. Response Interceptor (Örn: Veri Dönüşümü)
|
|
373
|
+
|
|
374
|
+
Gelen tüm response'ları merkezi olarak şekillendirebilir veya loglayabilirsiniz.
|
|
136
375
|
|
|
137
376
|
```typescript
|
|
138
377
|
import { HttpResponseInterceptor, Response } from '@yildizpay/http-adapter';
|
|
@@ -140,25 +379,30 @@ import { HttpResponseInterceptor, Response } from '@yildizpay/http-adapter';
|
|
|
140
379
|
export class TransformResponseInterceptor implements HttpResponseInterceptor {
|
|
141
380
|
async onResponse(response: Response): Promise<Response> {
|
|
142
381
|
if (response.status === 201) {
|
|
143
|
-
|
|
382
|
+
console.log('Kaynak başarıyla oluşturuldu!');
|
|
144
383
|
}
|
|
145
384
|
return response;
|
|
146
385
|
}
|
|
147
386
|
}
|
|
148
387
|
```
|
|
149
388
|
|
|
150
|
-
### 3.
|
|
151
|
-
|
|
389
|
+
### 3. Error Interceptor (Örn: Global Hata Yönetimi)
|
|
390
|
+
|
|
391
|
+
Sunucudan gelen hatalı HTTP kodlarını (4xx, 5xx) veya ağ hatalarını tek bir yerden yakalayıp yönetebilirsiniz.
|
|
152
392
|
|
|
153
393
|
```typescript
|
|
154
|
-
import {
|
|
394
|
+
import {
|
|
395
|
+
HttpErrorInterceptor,
|
|
396
|
+
Request,
|
|
397
|
+
BaseAdapterException,
|
|
398
|
+
UnauthorizedException,
|
|
399
|
+
} from '@yildizpay/http-adapter';
|
|
155
400
|
|
|
156
401
|
export class GlobalErrorInterceptor implements HttpErrorInterceptor {
|
|
157
|
-
async onError(error:
|
|
158
|
-
if (error instanceof
|
|
159
|
-
|
|
402
|
+
async onError(error: BaseAdapterException, request: Request): Promise<never> {
|
|
403
|
+
if (error instanceof UnauthorizedException) {
|
|
404
|
+
console.error(`${error.requestContext?.url} endpoint'ine yetkisiz erişim!`);
|
|
160
405
|
}
|
|
161
|
-
// Hatayı fırlatmaya devam edebilir veya varsayılan bir veri (fallback) dönebilirsiniz
|
|
162
406
|
throw error;
|
|
163
407
|
}
|
|
164
408
|
}
|
|
@@ -166,7 +410,7 @@ export class GlobalErrorInterceptor implements HttpErrorInterceptor {
|
|
|
166
410
|
|
|
167
411
|
## Katkıda Bulunma
|
|
168
412
|
|
|
169
|
-
Katkılarınızı her zaman bekliyoruz! Lütfen bir
|
|
413
|
+
Katkılarınızı her zaman bekliyoruz! Lütfen bir Pull Request göndermekten çekinmeyin.
|
|
170
414
|
|
|
171
415
|
## Lisans
|
|
172
416
|
|
|
@@ -2,6 +2,7 @@ import { HttpMethod } from '../common/enums/http-method.enum';
|
|
|
2
2
|
import { HttpBody } from '../common/types/http.types';
|
|
3
3
|
import { Request } from '../models/request';
|
|
4
4
|
import { RequestOptions } from '../models/request-options';
|
|
5
|
+
import { ResponseValidator } from '../contracts/response-validator.contract';
|
|
5
6
|
export declare class RequestBuilder {
|
|
6
7
|
private readonly baseUrl;
|
|
7
8
|
private endpoint;
|
|
@@ -10,6 +11,7 @@ export declare class RequestBuilder {
|
|
|
10
11
|
private body;
|
|
11
12
|
private queryParams;
|
|
12
13
|
private options;
|
|
14
|
+
private readonly validators;
|
|
13
15
|
constructor(baseUrl: string);
|
|
14
16
|
setEndpoint(endpoint: string): this;
|
|
15
17
|
setMethod(method: HttpMethod): this;
|
|
@@ -33,5 +35,6 @@ export declare class RequestBuilder {
|
|
|
33
35
|
resetQueryParams(): this;
|
|
34
36
|
setTimeout(timeout: number): this;
|
|
35
37
|
setOptions(options: RequestOptions): this;
|
|
38
|
+
validateWith(...validators: ResponseValidator[]): this;
|
|
36
39
|
build(): Request;
|
|
37
40
|
}
|
|
@@ -13,6 +13,7 @@ class RequestBuilder {
|
|
|
13
13
|
};
|
|
14
14
|
this.body = {};
|
|
15
15
|
this.queryParams = {};
|
|
16
|
+
this.validators = [];
|
|
16
17
|
this.baseUrl = baseUrl;
|
|
17
18
|
this.options = new request_options_1.RequestOptions();
|
|
18
19
|
}
|
|
@@ -104,8 +105,12 @@ class RequestBuilder {
|
|
|
104
105
|
this.options = options;
|
|
105
106
|
return this;
|
|
106
107
|
}
|
|
108
|
+
validateWith(...validators) {
|
|
109
|
+
this.validators.push(...validators);
|
|
110
|
+
return this;
|
|
111
|
+
}
|
|
107
112
|
build() {
|
|
108
|
-
return new request_1.Request(this.baseUrl, this.endpoint, this.method, this.headers, this.queryParams, this.body ? { ...this.body } : undefined, this.options);
|
|
113
|
+
return new request_1.Request(this.baseUrl, this.endpoint, this.method, this.headers, this.queryParams, this.body ? { ...this.body } : undefined, this.options, this.validators);
|
|
109
114
|
}
|
|
110
115
|
}
|
|
111
116
|
exports.RequestBuilder = RequestBuilder;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.builder.js","sourceRoot":"","sources":["../../src/builders/request.builder.ts"],"names":[],"mappings":";;;AAAA,uEAA8D;AAE9D,+CAA4C;AAC5C,+DAA2D;
|
|
1
|
+
{"version":3,"file":"request.builder.js","sourceRoot":"","sources":["../../src/builders/request.builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,12 +15,3 @@ export interface HttpClientResponse<T = unknown> {
|
|
|
15
15
|
export interface HttpClientContract {
|
|
16
16
|
request<T = unknown>(config: HttpClientRequestConfig): Promise<HttpClientResponse<T>>;
|
|
17
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
|
-
}
|
|
@@ -1,20 +1,3 @@
|
|
|
1
1
|
"use strict";
|
|
2
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
3
|
//# sourceMappingURL=http-client.contract.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-client.contract.js","sourceRoot":"","sources":["../../src/contracts/http-client.contract.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"http-client.contract.js","sourceRoot":"","sources":["../../src/contracts/http-client.contract.ts"],"names":[],"mappings":""}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BaseAdapterException } from '../exceptions/base-adapter.exception';
|
|
1
2
|
import { Request } from '../models/request';
|
|
2
3
|
import { Response } from '../models/response';
|
|
3
4
|
export interface HttpRequestInterceptor {
|
|
@@ -6,7 +7,10 @@ export interface HttpRequestInterceptor {
|
|
|
6
7
|
export interface HttpResponseInterceptor {
|
|
7
8
|
onResponse(response: Response): Promise<Response>;
|
|
8
9
|
}
|
|
10
|
+
export interface HttpValidatedResponseInterceptor {
|
|
11
|
+
onResponseValidated(response: Response): Promise<Response>;
|
|
12
|
+
}
|
|
9
13
|
export interface HttpErrorInterceptor {
|
|
10
|
-
onError(error:
|
|
14
|
+
onError(error: BaseAdapterException, request: Request): Promise<BaseAdapterException>;
|
|
11
15
|
}
|
|
12
|
-
export type HttpInterceptor = Partial<HttpRequestInterceptor> & Partial<HttpResponseInterceptor> & Partial<HttpErrorInterceptor>;
|
|
16
|
+
export type HttpInterceptor = Partial<HttpRequestInterceptor> & Partial<HttpResponseInterceptor> & Partial<HttpValidatedResponseInterceptor> & Partial<HttpErrorInterceptor>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-validator.contract.js","sourceRoot":"","sources":["../../src/contracts/response-validator.contract.ts"],"names":[],"mappings":""}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.defaultHttpClient = exports.FetchHttpClient = void 0;
|
|
4
|
-
const
|
|
4
|
+
const network_exception_factory_1 = require("../exceptions/network-exception.factory");
|
|
5
|
+
const http_exception_factory_1 = require("../exceptions/http-exception.factory");
|
|
6
|
+
const base_adapter_exception_1 = require("../exceptions/base-adapter.exception");
|
|
5
7
|
class FetchHttpClient {
|
|
6
8
|
async request(config) {
|
|
7
9
|
const controller = new AbortController();
|
|
@@ -32,7 +34,7 @@ class FetchHttpClient {
|
|
|
32
34
|
responseHeaders[key] = value;
|
|
33
35
|
});
|
|
34
36
|
if (!response.ok) {
|
|
35
|
-
throw
|
|
37
|
+
throw http_exception_factory_1.HttpExceptionFactory.createFromResponse(response.status, responseData, responseHeaders, `Request failed with status ${response.status}`);
|
|
36
38
|
}
|
|
37
39
|
return {
|
|
38
40
|
data: responseData,
|
|
@@ -41,10 +43,9 @@ class FetchHttpClient {
|
|
|
41
43
|
};
|
|
42
44
|
}
|
|
43
45
|
catch (error) {
|
|
44
|
-
if (error instanceof
|
|
45
|
-
throw
|
|
46
|
-
|
|
47
|
-
throw error;
|
|
46
|
+
if (error instanceof base_adapter_exception_1.BaseAdapterException)
|
|
47
|
+
throw error;
|
|
48
|
+
throw network_exception_factory_1.NetworkExceptionFactory.createFromNativeError(error);
|
|
48
49
|
}
|
|
49
50
|
finally {
|
|
50
51
|
if (timeoutId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-http-client.js","sourceRoot":"","sources":["../../src/core/default-http-client.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"default-http-client.js","sourceRoot":"","sources":["../../src/core/default-http-client.ts"],"names":[],"mappings":";;;AAKA,uFAAkF;AAClF,iFAA4E;AAC5E,iFAA4E;AAQ5E,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,6CAAoB,CAAC,kBAAkB,CAC3C,QAAQ,CAAC,MAAM,EACf,YAAiB,EACjB,eAAe,EACf,8BAA8B,QAAQ,CAAC,MAAM,EAAE,CAChD,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,6CAAoB;gBAAE,MAAM,KAAK,CAAC;YACvD,MAAM,mDAAuB,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;QAC7D,CAAC;gBAAS,CAAC;YACT,IAAI,SAAS,EAAE,CAAC;gBACd,YAAY,CAAC,SAAS,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;IACH,CAAC;CACF;AA3DD,0CA2DC;AAEY,QAAA,iBAAiB,GAAG,IAAI,eAAe,EAAE,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { BaseAdapterException } from '../exceptions/base-adapter.exception';
|
|
2
|
+
import { RequestContext } from '../models/request-context';
|
|
3
|
+
export declare class ErrorConverter {
|
|
4
|
+
static toAdapterException(error: unknown, requestContext?: RequestContext): BaseAdapterException;
|
|
5
|
+
}
|