http-request-manager 15.0.16 → 15.0.17
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 +274 -117
- package/http-request-manager-15.0.17.tgz +0 -0
- package/package.json +1 -1
- package/http-request-manager-15.0.16.tgz +0 -0
package/README.md
CHANGED
|
@@ -1,170 +1,327 @@
|
|
|
1
1
|
# Request Manager Service Documentation
|
|
2
2
|
|
|
3
3
|
## Summary of the Lib
|
|
4
|
-
The HTTPManagerService is
|
|
4
|
+
The HTTPManagerService is a collection of 4 services for HTTP and Local Storage management.
|
|
5
5
|
|
|
6
|
-
##
|
|
6
|
+
## Installation
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
This will allow the `http-request-manager` to use the app-id you assign as a encryption/decryption key for the `local-storage-manager`
|
|
8
|
+
`npm install http-request-manager`
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
{
|
|
13
|
-
provide: APP_ID,
|
|
14
|
-
useValue: '561324eb4fadb840330cd5ac4db67bef', // Replace with your unique application ID
|
|
15
|
-
},
|
|
16
|
-
AppService
|
|
17
|
-
```
|
|
10
|
+
## Services
|
|
18
11
|
|
|
19
|
-
|
|
20
|
-
### Error Handling
|
|
21
|
-
The example defines an errorRetry$ observable that captures errors using the catchError operator and enables retry logic. This observable can be utilized in your component templates to handle and display errors, making error management more flexible.
|
|
12
|
+
### HTTP Manager Service:
|
|
22
13
|
|
|
23
|
-
|
|
24
|
-
|
|
14
|
+
Http service simplifies http requests in the following ways
|
|
15
|
+
- Define a fixed endpoint service
|
|
16
|
+
- Provide a fixed set of headers or add to the headers on request
|
|
17
|
+
- Proxy Config Support
|
|
18
|
+
- Adapter for strict type checking for incoming data
|
|
19
|
+
- Mapper for data transformation for outgoing data
|
|
20
|
+
- Polling requests automatically
|
|
21
|
+
- Retry requests if failure
|
|
22
|
+
- Stream http requests from endpoint service
|
|
23
|
+
- Display Error provides a Toast (Snackbar) notification on error
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
apiRequest = ApiRequest.adapt({
|
|
28
|
-
server: 'nodebff/reporting-common-apis/v1',
|
|
29
|
-
path: ['dimensions','locations'],
|
|
30
|
-
adapter: DistrictData.adapt
|
|
31
|
-
});
|
|
32
|
-
```
|
|
25
|
+
### HTTP State Manager Service
|
|
33
26
|
|
|
34
|
-
|
|
35
|
-
|
|
27
|
+
Http service simplifies http request state management in the following ways
|
|
28
|
+
- Inherits from HTTP Manager Service for config options
|
|
29
|
+
- Creates a Component Store state (NGRX)
|
|
30
|
+
- Selectors for data and selecting data records
|
|
31
|
+
- Create, Update and Delete automatically updates data by endpoint and state on success
|
|
32
|
+
- Get keeps state of records
|
|
33
|
+
|
|
34
|
+
### Database Storage Manager (Coming soon)
|
|
35
|
+
- Inherits from HTTP State Manager Service for config options
|
|
36
|
+
- Manages HTTP Requests caching data in local DB (IndexedDB) using DixieJS
|
|
37
|
+
- Requests check first local DB and if data is not stale, request is made and updates DB
|
|
38
|
+
- Expiry time/date can be set for DB records for caching
|
|
39
|
+
|
|
40
|
+
### Local/Session Storage
|
|
41
|
+
- Allows for Local and Storage management for data Persistence
|
|
42
|
+
- Component Store (NGRX) State for changes on storage
|
|
43
|
+
- Encryption for data
|
|
44
|
+
- Expiry time/date can be set for stores
|
|
45
|
+
|
|
46
|
+
## Using the Services
|
|
47
|
+
|
|
48
|
+
There are three ways to use the service, depending on your needs:
|
|
49
|
+
|
|
50
|
+
### Injecting the Service (Single Usage)
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
httpManagerService = inject(HTTPManagerService)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
- This approach provides a singleton state for the service, as services are provided in root (@Injectable({ providedIn: 'root' })).
|
|
57
|
+
- Any components or services that inject this service will share the same state, meaning they all have access to:
|
|
58
|
+
- data$ (observable for data)
|
|
59
|
+
- isPending$ (loading state)
|
|
60
|
+
- countDown$ (loading state)
|
|
61
|
+
- error$ (error state)
|
|
62
|
+
- Methods associated with the service
|
|
63
|
+
- Since there is only one shared state, it can be reused across components without creating new instances.
|
|
64
|
+
|
|
65
|
+
Here is a very simple example
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
//Define your API request details using the `ApiRequest` adapter
|
|
69
|
+
const apiOptions = ApiRequest.adapt({
|
|
70
|
+
server: 'myApiUrl/rest/clients' // or ['myApiUrl', 'rest', 'clients']
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
onFetchData() {
|
|
74
|
+
|
|
75
|
+
this.httpManagerService.getRequest<any>(apiOptions)
|
|
76
|
+
.pipe(
|
|
77
|
+
catchError(error => {
|
|
78
|
+
return throwError(() => this.errorHandling(error, 'GET'))
|
|
79
|
+
})
|
|
80
|
+
).subscribe(data => console.log(data)))
|
|
81
|
+
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Example
|
|
86
|
+
In this example, we define the endpoint URL as myApiUrl. This will return the data from the observable for your use case.
|
|
87
|
+
|
|
88
|
+
The endpoint can be:
|
|
89
|
+
|
|
90
|
+
A direct URL (e.g., https://apple.com/clients).
|
|
91
|
+
A proxy-config file (recommended to avoid CORS issues).
|
|
92
|
+
A string, an array of strings, or numbers—similar to Angular’s Router.navigate() API.
|
|
93
|
+
The HTTP Service Manager automatically sanitizes the endpoint by removing redundant `/` characters and validating the URL.
|
|
94
|
+
|
|
95
|
+
You can also add query parameters by passing an object:
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
{ sortBy: 'asc', filter: ['samples', 'testing'] }
|
|
99
|
+
```
|
|
36
100
|
|
|
101
|
+
This translates to: `https://apple.com/clients?sortBy=asc&filter=samples,testing`
|
|
102
|
+
|
|
103
|
+
There are a number of other options available in the `ApiRequest` adapter
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
### Extending a Component or Service with the Service (Multiple Instances - preferred method)
|
|
107
|
+
|
|
108
|
+
This approach creates a new instance of the service for each component or service that extends it, ensuring each instance maintains its own independent state.
|
|
109
|
+
|
|
110
|
+
### Observables
|
|
111
|
+
- Similar to the first approach, instead of one instance of the state you are creating a new state instance
|
|
112
|
+
- CRUD operations return Observables, similar to HttpClient.
|
|
113
|
+
- This allows for custom error handling and executing additional actions after the request completes.
|
|
114
|
+
- Since HTTP requests are asynchronous, you must subscribe to the Observable to receive data:
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
myService.getData().subscribe(response => {
|
|
118
|
+
console.log(response);
|
|
119
|
+
});
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
- Alternatively, you can use the async pipe for automatic subscription and cleanup:
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
{{ myData$ | async }}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Example
|
|
129
|
+
First we need to extend the Component or Service (recommended approach) with the `HTTPManagerService`
|
|
130
|
+
|
|
131
|
+
Component Example:
|
|
132
|
+
```ts
|
|
133
|
+
export class RequestManagerDemoComponent extends HTTPManagerService<any> implements OnInit {
|
|
134
|
+
|
|
135
|
+
constructor() {
|
|
136
|
+
super()
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Service Example:
|
|
142
|
+
```ts
|
|
143
|
+
@Injectable({
|
|
144
|
+
providedIn: 'root'
|
|
145
|
+
})
|
|
146
|
+
export class myAPIService extends HTTPManagerService<any> {
|
|
147
|
+
|
|
148
|
+
constructor() {
|
|
149
|
+
super()
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
In this example, we define the endpoint URL as myApiUrl. This will return the data from the observable for your use case.
|
|
156
|
+
|
|
157
|
+
The endpoint can be:
|
|
158
|
+
|
|
159
|
+
A direct URL (e.g., https://apple.com/clients).
|
|
160
|
+
A proxy-config file (recommended to avoid CORS issues).
|
|
161
|
+
A string, an array of strings, or numbers—similar to Angular’s Router.navigate() API.
|
|
162
|
+
The HTTP Service Manager automatically sanitizes the endpoint by removing redundant `/` characters and validating the URL.
|
|
163
|
+
|
|
164
|
+
You can also add query parameters by passing an object:
|
|
37
165
|
```ts
|
|
38
|
-
|
|
39
|
-
server: string,
|
|
40
|
-
path: any[],
|
|
41
|
-
headers: any,
|
|
42
|
-
adapter?: any,
|
|
43
|
-
mapper?: any,
|
|
44
|
-
polling?: number, // in seconds (undefined | 0 = none)
|
|
45
|
-
retry: RetryOptions,
|
|
46
|
-
stream?: boolean
|
|
47
|
-
displayError: boolean
|
|
48
|
-
});
|
|
166
|
+
{ sortBy: 'asc', filter: ['samples', 'testing'] }
|
|
49
167
|
```
|
|
168
|
+
This translates to: `https://apple.com/clients?sortBy=asc&filter=samples,testing`
|
|
50
169
|
|
|
51
|
-
|
|
52
|
-
- path: Additional paths to append to the base URL for constructing the full API endpoint.
|
|
53
|
-
- headers: Custom headers to include in the request, provided as an object.
|
|
54
|
-
- adapter (incoming): A model adapter used to transform incoming data (e.g., DistrictData.adapt).
|
|
55
|
-
- mapper (outgoing): A model adapter used to map outgoing data before sending it to the server (e.g., DistrictData.mapper).
|
|
56
|
-
- polling: Enables periodic polling, where the request will be made every specified number of seconds.
|
|
57
|
-
- retry: Retry logic using RetryOptions, which includes:
|
|
58
|
-
- times: Number of retry attempts.
|
|
59
|
-
- delay: Delay in milliseconds between each retry.
|
|
60
|
-
- stream: A flag to indicate whether the request expects a stream of data from the server.
|
|
61
|
-
- displayError: A flag to indicate whether to present the error from the request in a snackBar notification
|
|
170
|
+
Lets define these query params as a variable called `PARAMS` and use them in the following request.
|
|
62
171
|
|
|
63
|
-
|
|
64
|
-
- countdown$: If polling is active, this property gives feedback on when the next request will take place. It starts from the specified time in seconds and counts down to 0, triggering the next request and restarting the countdown.
|
|
65
|
-
- error$: This returns any HTTP error that occurs during the request.
|
|
66
|
-
- isPending$: This boolean value indicates whether the request is pending (true) or has been completed (false).
|
|
67
|
-
- data$: You can access the data fetched in the request using the data$ observable. This provides the response from the server, which can be used for further processing or displaying in the UI.
|
|
172
|
+
There are a number of other options available in the `ApiRequest` adapter
|
|
68
173
|
|
|
69
|
-
|
|
70
|
-
|
|
174
|
+
No we can define a method:
|
|
175
|
+
In this example take note that the clientID has been passed to the method and the param after the apiOptions allows for further customization for the api request being made. In this case we extended the the base path defined in the `ApiRequest` options. We also added the `PARAMS` for query parameters.
|
|
71
176
|
|
|
72
|
-
|
|
177
|
+
Define your API request options using the 'ApiRequest' adapter
|
|
73
178
|
|
|
74
|
-
```ts
|
|
75
|
-
|
|
179
|
+
```ts
|
|
180
|
+
const apiOptions = ApiRequest.adapt({
|
|
181
|
+
server: ['myApiUrl', 'rest', 'clients']
|
|
182
|
+
})
|
|
76
183
|
|
|
77
|
-
//
|
|
184
|
+
// Dynamically change these params
|
|
185
|
+
const PARAMS = {
|
|
186
|
+
sortBy: 'asc',
|
|
187
|
+
filter: ['samples', 'testing']
|
|
188
|
+
}
|
|
78
189
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
httpManagerService = inject(HTTPManagerService);
|
|
190
|
+
onFetchData(clientId) {
|
|
82
191
|
|
|
83
|
-
|
|
84
|
-
|
|
192
|
+
this.httpManagerService.getRequest<any>(apiOptions, [clientId, this.PARAMS])
|
|
193
|
+
.pipe(
|
|
194
|
+
catchError(error => {
|
|
195
|
+
return throwError(() => this.errorHandling(error, 'GET'))
|
|
196
|
+
})
|
|
197
|
+
).subscribe(data => console.log(data)))
|
|
85
198
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
path: ['dimensions','locations'],
|
|
89
|
-
adapter: DistrictData.adapt
|
|
90
|
-
});
|
|
199
|
+
}
|
|
200
|
+
```
|
|
91
201
|
|
|
92
|
-
params = {
|
|
93
|
-
type: 'DISTRICT',
|
|
94
|
-
excludeEcom: true
|
|
95
|
-
};
|
|
96
202
|
|
|
97
|
-
|
|
203
|
+
### State Observable
|
|
204
|
+
- When executing CRUD operations, their results are automatically pushed into the data$ observable within the service.
|
|
205
|
+
- This means you can bind the data$ observable to a component to automatically update UI elements.
|
|
206
|
+
- Using this approach enables state management across components and allows data refresh actions without needing additional logic.
|
|
98
207
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
catchError((error: HttpErrorResponse) => {
|
|
102
|
-
|
|
103
|
-
// custom retry logic
|
|
104
|
-
const func = this.fetchDistrictData.bind(this);
|
|
105
|
-
const message = error.message;
|
|
106
|
-
this.errorRetry.next({ func, message });
|
|
208
|
+
### Example
|
|
209
|
+
First we need to extend the Component or Service (recommended approach) with the `HTTPManagerService`
|
|
107
210
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
);
|
|
211
|
+
Component Example:
|
|
212
|
+
The structure would be: Component extends `HTTPManagerService`
|
|
111
213
|
|
|
214
|
+
```ts
|
|
215
|
+
export class RequestManagerDemoComponent extends HTTPManagerService<any> implements OnInit {
|
|
216
|
+
|
|
217
|
+
constructor() {
|
|
218
|
+
super()
|
|
219
|
+
}
|
|
112
220
|
}
|
|
221
|
+
```
|
|
113
222
|
|
|
114
|
-
|
|
115
|
-
|
|
223
|
+
Service Example:
|
|
224
|
+
The structure would be: Component injects a service call `clientsService` and `clientsService` extends `HTTPManagerService`
|
|
116
225
|
|
|
117
|
-
|
|
226
|
+
```ts
|
|
227
|
+
@Injectable({
|
|
228
|
+
providedIn: 'root'
|
|
229
|
+
})
|
|
230
|
+
export class myAPIService extends HTTPManagerService<any> {
|
|
118
231
|
|
|
119
|
-
|
|
232
|
+
constructor() {
|
|
233
|
+
super()
|
|
234
|
+
}
|
|
120
235
|
|
|
121
|
-
|
|
122
|
-
|
|
236
|
+
}
|
|
237
|
+
```
|
|
123
238
|
|
|
124
|
-
|
|
125
|
-
The fetchDistrictData() method calls the getRequest function and immediately subscribes to the result. Since it subscribes, the request is made and the result is handled within the data$ observable.
|
|
126
|
-
If an error occurs during the request, the error is caught using catchError. The errorRetry$ observable is updated with the error details, which can be handled in the component or template.
|
|
239
|
+
In this example, we define the endpoint URL as myApiUrl.
|
|
127
240
|
|
|
128
|
-
|
|
129
|
-
fetchDistrictData() {
|
|
241
|
+
Lets define these query params as a variable called `PARAMS` and use them in the following request.
|
|
130
242
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
243
|
+
No we can define a method:
|
|
244
|
+
In this example the clientID has been passed to the method.
|
|
245
|
+
We also added the `PARAMS` for query parameters.
|
|
134
246
|
|
|
135
|
-
|
|
136
|
-
const message = error.message
|
|
137
|
-
this.errorRetry.next({ func, message })
|
|
247
|
+
Define your API request options using the 'ApiRequest' adapter
|
|
138
248
|
|
|
139
|
-
|
|
249
|
+
```ts
|
|
250
|
+
const apiOptions = ApiRequest.adapt({
|
|
251
|
+
server: ['myApiUrl', 'rest', 'clients']
|
|
140
252
|
})
|
|
141
|
-
).subscribe()
|
|
142
253
|
|
|
143
|
-
|
|
144
|
-
|
|
254
|
+
// Dynamically change these params
|
|
255
|
+
const PARAMS = {
|
|
256
|
+
sortBy: 'asc',
|
|
257
|
+
filter: ['samples', 'testing']
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
onFetchData(clientId: number) {
|
|
261
|
+
this.httpManagerService.getRequest<any>(apiOptions, [clientId, this.PARAMS]).subscribe()
|
|
262
|
+
}
|
|
263
|
+
```
|
|
145
264
|
|
|
146
|
-
|
|
147
|
-
The result of the request is stored in the data$ observable, which is inherited from the parent class (HTTPManagerService). This observable is connected to a component for further usage.
|
|
265
|
+
In the above case we are not using the data returning from the Observable but rather executing the api call, like a refresh if called again
|
|
148
266
|
|
|
149
|
-
|
|
150
|
-
|
|
267
|
+
To access the data from the observable, you need to bind the observable if your using a component that injects the service that extends the `HTTPManagerService`
|
|
268
|
+
|
|
269
|
+
In the component where the service was injected, we define
|
|
270
|
+
|
|
271
|
+
```ts
|
|
272
|
+
data$ = this.clientsService.data$
|
|
273
|
+
isPending$ = this.clientsService.isPending$
|
|
274
|
+
error$ = this.clientsService.error$
|
|
275
|
+
```
|
|
276
|
+
By doing this gives your component the state of the data and other feedback states for the request that now you can use in your template.
|
|
151
277
|
|
|
152
278
|
```ts
|
|
153
|
-
|
|
279
|
+
{{ data$ | async }}
|
|
280
|
+
{{ isPending$ | async }}
|
|
281
|
+
{{ error$ | async }}
|
|
154
282
|
```
|
|
155
283
|
|
|
156
|
-
This data$ observable is then used in the template to display the data asynchronously:
|
|
157
284
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
285
|
+
### ApiRequest Options
|
|
286
|
+
The following are the available options when configuring an ApiRequest object:
|
|
287
|
+
|
|
288
|
+
```ts
|
|
289
|
+
apiRequest = ApiRequest.adapt({
|
|
290
|
+
server: string,
|
|
291
|
+
path: any[],
|
|
292
|
+
headers: any,
|
|
293
|
+
adapter?: any,
|
|
294
|
+
mapper?: any,
|
|
295
|
+
polling?: number, // in seconds (undefined | 0 = none)
|
|
296
|
+
retry: RetryOptions,
|
|
297
|
+
stream?: boolean
|
|
298
|
+
displayError: boolean
|
|
299
|
+
});
|
|
162
300
|
```
|
|
163
301
|
|
|
164
|
-
|
|
302
|
+
| **Property** | **Description** | **Type** | **Required** |
|
|
303
|
+
|--------------|--------------------------------------------------------------------------------|---------------------------|------------|
|
|
304
|
+
| `server` | The base URL or service endpoint for the API request. | `string` | ✅ |
|
|
305
|
+
| `path` | Additional paths to append to the base URL for constructing the full API endpoint. | `any[]` | ✅ |
|
|
306
|
+
| `headers` | Custom headers to include in the request, provided as an object. | `any` | ✅ |
|
|
307
|
+
| `adapter` | A model adapter used to transform incoming data (e.g., `DistrictData.adapt`). | `any` | ❌ |
|
|
308
|
+
| `mapper` | A model adapter used to map outgoing data before sending it to the server (e.g., `DistrictData.mapper`). | `any` | ❌ |
|
|
309
|
+
| `polling` | Enables periodic polling, where the request will be made every specified number of seconds. | `number` (seconds) | ❌ |
|
|
310
|
+
| `retry` | Retry logic using `RetryOptions`, which includes: <br> - `times`: Number of retry attempts. <br> - `delay`: Delay in milliseconds between retries. | `RetryOptions` | ✅ |
|
|
311
|
+
| `stream` | A flag to indicate whether the request expects a stream of data from the server. | `boolean` | ❌ |
|
|
312
|
+
| `displayError` | A flag to indicate whether to present the error from the request in a snackbar notification. | `boolean` | ✅ |
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
### Additional Observables for Request Status
|
|
316
|
+
- countdown$: If polling is active, this property gives feedback on when the next request will take place. It starts from the specified time in seconds and counts down to 0, triggering the next request and restarting the countdown.
|
|
317
|
+
- error$: This returns any HTTP error that occurs during the request.
|
|
318
|
+
- isPending$: This boolean value indicates whether the request is pending (true) or has been completed (false).
|
|
319
|
+
- data$: You can access the data fetched in the request using the data$ observable. This provides the response from the server, which can be used for further processing or displaying in the UI.
|
|
320
|
+
|
|
321
|
+
## Importing Module forRoot() Configuration
|
|
165
322
|
|
|
166
323
|
|
|
167
|
-
# Interceptors
|
|
324
|
+
# Available Interceptors
|
|
168
325
|
|
|
169
326
|
There are 3 interceptors that you can import into your project for api requests.
|
|
170
327
|
|
|
Binary file
|
package/package.json
CHANGED
|
Binary file
|