refactor: implement RequestBuilder for main request

This commit is contained in:
2024-06-27 01:50:58 +03:00
parent e36376db3a
commit 8e738d9b3d
9 changed files with 151 additions and 75 deletions

View File

@ -1,9 +1,10 @@
import {catchError, mergeMap, Observable, retryWhen, timer} from "rxjs";
import {catchError, mergeMap, Observable, retryWhen, tap, timer} from "rxjs";
import {HttpClient, HttpErrorResponse} from "@angular/common/http";
import {NotifyColor, OpenNotifyService} from "@service/open-notify.service";
import {environment} from "@environment";
import {Router} from "@angular/router";
import {Injectable} from "@angular/core";
import {RequestBuilder, RequestData, SetRequestBuilderAfterBuild} from "@api/RequestBuilder";
export function retryWithInterval<T>(): (source: Observable<T>) => Observable<T> {
return (source: Observable<T>) =>
@ -28,24 +29,23 @@ export function retryWithInterval<T>(): (source: Observable<T>) => Observable<T>
);
}
/*
@Injectable({
providedIn: 'root'
})
*/
export enum AvailableVersion {
v1
}
@Injectable()
export default abstract class ApiService {
export default abstract class ApiService implements SetRequestBuilderAfterBuild {
constructor(private http: HttpClient, private notify: OpenNotifyService, private router: Router) {
}
private urlApi = environment.apiUrl;
protected abstract basePath: string;
protected abstract version: AvailableVersion;
private request: RequestData = RequestBuilder.getStandardRequestData();
public setRequestBuilder(request: RequestData): void {
this.request = request;
}
private static addQuery(endpoint: string, queryParams?: Record<string, string | number | boolean | Array<any> | null> | null): string {
const url = new URL(endpoint);
@ -54,10 +54,9 @@ export default abstract class ApiService {
Object.keys(queryParams).forEach(key => {
const value = queryParams[key];
if (value !== null && value !== undefined) {
if (typeof(value) === typeof(Array)) {
if (typeof (value) === typeof (Array)) {
(value as Array<any>).forEach(x => url.searchParams.append(key, x.toString()));
}
else
} else
url.searchParams.append(key, value.toString());
}
});
@ -72,50 +71,59 @@ export default abstract class ApiService {
return test;
}
public get<Type>(endpoint: string = '', queryParams: Record<string, string | number | boolean | Array<any> | null> | null = null): Observable<Type> {
return this.http.get<Type>(ApiService.addQuery(ApiService.combineUrls(this.urlApi, AvailableVersion[this.version], this.basePath, endpoint), queryParams), {withCredentials: true}).pipe(
private makeHttpRequest<Type>(method: 'get' | 'post' | 'delete' | 'put'): Observable<Type> {
const doneEndpoint = ApiService.addQuery(ApiService.combineUrls(this.urlApi, AvailableVersion[this.version], this.basePath, this.request.endpoint), this.request.queryParams);
return this.http.request<Type>(method, doneEndpoint, {
withCredentials: true,
headers: this.request.httpHeaders,
body: this.request.data
}).pipe(
tap(_ => this.request = RequestBuilder.getStandardRequestData()),
retryWithInterval<Type>(),
catchError(error => {
this.handleError(error);
if (!this.request.silenceMode)
this.handleError(error);
this.request = RequestBuilder.getStandardRequestData();
throw error;
})
})
);
}
public post<Type>(endpoint: string, data: any, queryParams: Record<string, string | number | boolean | Array<any> | null> | null = null): Observable<Type> {
return this.http.post<Type>(ApiService.addQuery(ApiService.combineUrls(this.urlApi, AvailableVersion[this.version], this.basePath, endpoint), queryParams), data, {withCredentials: true}).pipe(
retryWithInterval<Type>(),
catchError(error => {
this.handleError(error);
throw error;
})
);
public createRequestBuilder() {
this.request = RequestBuilder.getStandardRequestData();
return new RequestBuilder(this);
}
public put<Type>(endpoint: string, data: any, queryParams: Record<string, string | number | boolean | Array<any> | null> | null = null): Observable<Type> {
return this.http.put<Type>(ApiService.addQuery(ApiService.combineUrls(this.urlApi, AvailableVersion[this.version], this.basePath, endpoint), queryParams), data, {withCredentials: true}).pipe(
retryWithInterval<Type>(),
catchError(error => {
this.handleError(error);
throw error;
})
);
public get<Type>(endpoint: string = ''): Observable<Type> {
if (endpoint)
this.request.endpoint = endpoint;
return this.makeHttpRequest<Type>('get');
}
public delete<Type>(endpoint: string): Observable<Type> {
return this.http.delete<Type>(ApiService.combineUrls(this.urlApi, AvailableVersion[this.version], this.basePath, endpoint), {withCredentials: true}).pipe(
retryWithInterval<Type>(),
catchError(error => {
this.handleError(error);
throw error;
})
);
public post<Type>(endpoint: string = ''): Observable<Type> {
if (endpoint)
this.request.endpoint = endpoint;
return this.makeHttpRequest<Type>('post');
}
public put<Type>(endpoint: string = ''): Observable<Type> {
if (endpoint)
this.request.endpoint = endpoint;
return this.makeHttpRequest<Type>('put');
}
public delete<Type>(endpoint: string = ''): Observable<Type> {
if (endpoint)
this.request.endpoint = endpoint;
return this.makeHttpRequest<Type>('delete');
}
private handleError(error: HttpErrorResponse): void {
// todo: change to Retry-After condition
if (error.error.toString().includes("setup")) {
this.router.navigate(['/setup/']);
this.router.navigate(['/setup/']).then();
return;
}