From 8e738d9b3dee1bf154edf1743c7bd8efef430ada Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Thu, 27 Jun 2024 01:50:58 +0300 Subject: [PATCH] refactor: implement RequestBuilder for main request --- src/api/api.service.ts | 88 +++++++++++++++++-------------- src/api/v1/campus.service.ts | 4 +- src/api/v1/discipline.service.ts | 9 ++-- src/api/v1/faculty.service.ts | 9 ++-- src/api/v1/group.service.ts | 9 ++-- src/api/v1/lectureHall.service.ts | 4 +- src/api/v1/professor.service.ts | 9 ++-- src/api/v1/schedule.service.ts | 33 +++++++++--- src/api/v1/setup.service.ts | 61 ++++++++++++++++----- 9 files changed, 151 insertions(+), 75 deletions(-) diff --git a/src/api/api.service.ts b/src/api/api.service.ts index 4717279..a8047a9 100644 --- a/src/api/api.service.ts +++ b/src/api/api.service.ts @@ -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(): (source: Observable) => Observable { return (source: Observable) => @@ -28,24 +29,23 @@ export function retryWithInterval(): (source: Observable) => Observable ); } -/* -@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 | 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).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(endpoint: string = '', queryParams: Record | null> | null = null): Observable { - return this.http.get(ApiService.addQuery(ApiService.combineUrls(this.urlApi, AvailableVersion[this.version], this.basePath, endpoint), queryParams), {withCredentials: true}).pipe( + private makeHttpRequest(method: 'get' | 'post' | 'delete' | 'put'): Observable { + const doneEndpoint = ApiService.addQuery(ApiService.combineUrls(this.urlApi, AvailableVersion[this.version], this.basePath, this.request.endpoint), this.request.queryParams); + + return this.http.request(method, doneEndpoint, { + withCredentials: true, + headers: this.request.httpHeaders, + body: this.request.data + }).pipe( + tap(_ => this.request = RequestBuilder.getStandardRequestData()), retryWithInterval(), catchError(error => { - this.handleError(error); + if (!this.request.silenceMode) + this.handleError(error); + + this.request = RequestBuilder.getStandardRequestData(); throw error; - }) + }) ); } - public post(endpoint: string, data: any, queryParams: Record | null> | null = null): Observable { - return this.http.post(ApiService.addQuery(ApiService.combineUrls(this.urlApi, AvailableVersion[this.version], this.basePath, endpoint), queryParams), data, {withCredentials: true}).pipe( - retryWithInterval(), - catchError(error => { - this.handleError(error); - throw error; - }) - ); + public createRequestBuilder() { + this.request = RequestBuilder.getStandardRequestData(); + return new RequestBuilder(this); } - public put(endpoint: string, data: any, queryParams: Record | null> | null = null): Observable { - return this.http.put(ApiService.addQuery(ApiService.combineUrls(this.urlApi, AvailableVersion[this.version], this.basePath, endpoint), queryParams), data, {withCredentials: true}).pipe( - retryWithInterval(), - catchError(error => { - this.handleError(error); - throw error; - }) - ); + public get(endpoint: string = ''): Observable { + if (endpoint) + this.request.endpoint = endpoint; + return this.makeHttpRequest('get'); } - public delete(endpoint: string): Observable { - return this.http.delete(ApiService.combineUrls(this.urlApi, AvailableVersion[this.version], this.basePath, endpoint), {withCredentials: true}).pipe( - retryWithInterval(), - catchError(error => { - this.handleError(error); - throw error; - }) - ); + public post(endpoint: string = ''): Observable { + if (endpoint) + this.request.endpoint = endpoint; + return this.makeHttpRequest('post'); + } + + public put(endpoint: string = ''): Observable { + if (endpoint) + this.request.endpoint = endpoint; + return this.makeHttpRequest('put'); + } + + public delete(endpoint: string = ''): Observable { + if (endpoint) + this.request.endpoint = endpoint; + return this.makeHttpRequest('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; } diff --git a/src/api/v1/campus.service.ts b/src/api/v1/campus.service.ts index 1a02d97..f943f38 100644 --- a/src/api/v1/campus.service.ts +++ b/src/api/v1/campus.service.ts @@ -5,8 +5,8 @@ import {CampusDetailsResponse} from "@api/v1/campusDetailsResponse"; @Injectable() export class CampusService extends ApiService { - protected basePath = 'Campus/'; - protected version = AvailableVersion.v1; + public readonly basePath = 'Campus/'; + public readonly version = AvailableVersion.v1; public getCampus() { return this.get(); diff --git a/src/api/v1/discipline.service.ts b/src/api/v1/discipline.service.ts index 143c5a1..e929f71 100644 --- a/src/api/v1/discipline.service.ts +++ b/src/api/v1/discipline.service.ts @@ -4,11 +4,14 @@ import {DisciplineResponse} from "@api/v1/disciplineResponse"; @Injectable() export class DisciplineService extends ApiService { - protected basePath = 'Discipline/'; - protected version = AvailableVersion.v1; + public readonly basePath = 'Discipline/'; + public readonly version = AvailableVersion.v1; public getDisciplines(page: number | null = null, pageSize: number | null = null) { - return this.get('', {page: page, pageSize: pageSize}); + return this.createRequestBuilder() + .setQueryParams({page: page, pageSize: pageSize}) + .build() + .get(); } public getById(id: number) { diff --git a/src/api/v1/faculty.service.ts b/src/api/v1/faculty.service.ts index 64b8511..7e188a3 100644 --- a/src/api/v1/faculty.service.ts +++ b/src/api/v1/faculty.service.ts @@ -5,11 +5,14 @@ import {FacultyDetailsResponse} from "@api/v1/facultyDetailsResponse"; @Injectable() export class FacultyService extends ApiService { - protected basePath = 'Faculty/'; - protected version = AvailableVersion.v1; + public readonly basePath = 'Faculty/'; + public readonly version = AvailableVersion.v1; public getFaculties(page: number | null = null, pageSize: number | null = null) { - return this.get('', {page: page, pageSize: pageSize}); + return this.createRequestBuilder() + .setQueryParams({page: page, pageSize: pageSize}) + .build() + .get(); } diff --git a/src/api/v1/group.service.ts b/src/api/v1/group.service.ts index d990c0d..4c634be 100644 --- a/src/api/v1/group.service.ts +++ b/src/api/v1/group.service.ts @@ -5,11 +5,14 @@ import {GroupDetailsResponse} from "@api/v1/groupDetailsResponse"; @Injectable() export class GroupService extends ApiService { - protected basePath = 'Group/'; - protected version = AvailableVersion.v1; + public readonly basePath = 'Group/'; + public readonly version = AvailableVersion.v1; public getGroups(page: number | null = null, pageSize: number | null = null) { - return this.get('', {page: page, pageSize: pageSize}); + return this.createRequestBuilder() + .setQueryParams({page: page, pageSize: pageSize}) + .build() + .get(); } public getById(id: number) { diff --git a/src/api/v1/lectureHall.service.ts b/src/api/v1/lectureHall.service.ts index d2e74bf..e1645c0 100644 --- a/src/api/v1/lectureHall.service.ts +++ b/src/api/v1/lectureHall.service.ts @@ -5,8 +5,8 @@ import {LectureHallDetailsResponse} from "@api/v1/lectureHallDetailsResponse"; @Injectable() export class LectureHallService extends ApiService { - protected basePath = 'LectureHall/'; - protected version = AvailableVersion.v1; + public readonly basePath = 'LectureHall/'; + public readonly version = AvailableVersion.v1; public getLectureHalls() { return this.get(); diff --git a/src/api/v1/professor.service.ts b/src/api/v1/professor.service.ts index fe20e32..5c3717f 100644 --- a/src/api/v1/professor.service.ts +++ b/src/api/v1/professor.service.ts @@ -4,11 +4,14 @@ import {ProfessorResponse} from "@api/v1/professorResponse"; @Injectable() export class ProfessorService extends ApiService { - protected basePath = 'Professor/'; - protected version = AvailableVersion.v1; + public readonly basePath = 'Professor/'; + public readonly version = AvailableVersion.v1; public getProfessors(page: number | null = null, pageSize: number | null = null) { - return this.get('', {page: page, pageSize: pageSize}); + return this.createRequestBuilder() + .setQueryParams({page: page, pageSize: pageSize}) + .build() + .get(); } public getById(id: number) { diff --git a/src/api/v1/schedule.service.ts b/src/api/v1/schedule.service.ts index b4b45f0..a0d6ae4 100644 --- a/src/api/v1/schedule.service.ts +++ b/src/api/v1/schedule.service.ts @@ -8,8 +8,8 @@ import {map} from "rxjs"; @Injectable() export class ScheduleService extends ApiService { - protected basePath = 'Schedule/'; - protected version = AvailableVersion.v1; + public readonly basePath = 'Schedule/'; + public readonly version = AvailableVersion.v1; public startTerm() { return this.get('StartTerm').pipe(map(date => new DateOnly(date))); @@ -20,22 +20,41 @@ export class ScheduleService extends ApiService { } public postSchedule(data: ScheduleRequest) { - return this.post('', data); + return this.createRequestBuilder() + .setData(data) + .build() + .post(); } public getByGroup(id : number, isEven: boolean | null = null, disciplines: Array | null = null, professors: Array | null = null, lectureHalls: Array | null = null) { - return this.get('GetByGroup/' + id.toString(), {isEven: isEven, disciplines: disciplines, professors: professors, lectureHalls: lectureHalls}); + return this.createRequestBuilder() + .setEndpoint('GetByGroup/' + id.toString()) + .setQueryParams({isEven: isEven, disciplines: disciplines, professors: professors, lectureHalls: lectureHalls}) + .build() + .get(); } public getByProfessor(id : number, isEven: boolean | null = null, disciplines: Array | null = null, groups: Array | null = null, lectureHalls: Array | null = null) { - return this.get('GetByProfessor/' + id.toString(), {isEven: isEven, disciplines: disciplines, groups: groups, lectureHalls: lectureHalls}); + return this.createRequestBuilder() + .setEndpoint('GetByProfessor/' + id.toString()) + .setQueryParams({isEven: isEven, disciplines: disciplines, groups: groups, lectureHalls: lectureHalls}) + .build() + .get(); } public getByLectureHall(id : number, isEven: boolean | null = null, disciplines: Array | null = null, groups: Array | null = null, professors: Array | null = null) { - return this.get('GetByLectureHall/' + id.toString(), {isEven: isEven, disciplines: disciplines, groups: groups, professors: professors}); + return this.createRequestBuilder() + .setEndpoint('GetByLectureHall/' + id.toString()) + .setQueryParams({isEven: isEven, disciplines: disciplines, groups: groups, professors: professors}) + .build() + .get(); } public getByDiscipline(id : number, isEven: boolean | null = null, groups: Array | null = null, professors: Array | null = null, lectureHalls: Array | null = null) { - return this.get('GetByDiscipline/' + id.toString(), {isEven: isEven, groups: groups, professors: professors, lectureHalls: lectureHalls}); + return this.createRequestBuilder() + .setEndpoint('GetByDiscipline/' + id.toString()) + .setQueryParams({isEven: isEven, groups: groups, professors: professors, lectureHalls: lectureHalls}) + .build() + .get(); } } diff --git a/src/api/v1/setup.service.ts b/src/api/v1/setup.service.ts index 0e54bee..8cfc3ca 100644 --- a/src/api/v1/setup.service.ts +++ b/src/api/v1/setup.service.ts @@ -10,51 +10,88 @@ import {DateOnly} from "@model/DateOnly"; @Injectable() export default class SetupService extends ApiService { - protected basePath = 'Setup/'; + public readonly basePath = 'Setup/'; public readonly version = AvailableVersion.v1; public checkToken(token: string) { - return this.get('CheckToken', {token: token}); + return this.createRequestBuilder() + .setEndpoint('CheckToken') + .setQueryParams({token: token}) + .build() + .get(); } public setPsql(data: DatabaseRequest) { - return this.post('SetPsql', data); + return this.createRequestBuilder() + .setEndpoint('SetPsql') + .setData(data) + .build() + .post(); } public setMysql(data: DatabaseRequest) { - return this.post('SetMysql', data); + return this.createRequestBuilder() + .setEndpoint('SetMysql') + .setData(data) + .build() + .post(); } public setSqlite(path: string | null = null) { - return this.post('SetSqlite', null, {path: path}); + return this.createRequestBuilder() + .setEndpoint('SetSqlite') + .setQueryParams({path: path}) + .build() + .get(); } public setRedis(data: CacheRequest) { - return this.post('SetRedis', data); + return this.createRequestBuilder() + .setEndpoint('SetRedis') + .setData(data) + .build() + .post(); } public setMemcached() { - return this.post('SetMemcached', null); + return this.post('SetMemcached'); } public createAdmin(data: CreateUserRequest) { - return this.post('CreateAdmin', data); + return this.createRequestBuilder() + .setEndpoint('CreateAdmin') + .setData(data) + .build() + .post(); } public setLogging(data: LoggingRequest | null = null) { - return this.post('SetLogging', data); + return this.createRequestBuilder() + .setEndpoint('SetLogging') + .setData(data) + .build() + .post(); } public setEmail(data: EmailRequest | null = null) { - return this.post('SetEmail', data); + return this.createRequestBuilder() + .setEndpoint('SetEmail') + .setData(data) + .build() + .post(); } public setSchedule(data: ScheduleConfigurationRequest) { data.startTerm = new DateOnly(data.startTerm).toString(); - return this.post('SetSchedule', data); + + return this.createRequestBuilder() + .setEndpoint('SetSchedule') + .setData(data) + .build() + .post(); } public submit() { - return this.post('Submit', null); + return this.post('Submit'); } }