ngx-api-manager
Version:
Module for configuration http requests
114 lines (113 loc) • 8.87 kB
TypeScript
/**
* @desc - Единый сервис для выполнения HTTP запросов. Конфигурирует запрос - установка url, метода запроса, токена и др.
*
* Как применять читайте в Readme.md находящимся в корне модуля или в документации. Как сгенерировать документация
* описанно в корневом Readme.md
*
* Решает следующие основные задачи. Единый поток для http ошибок и фильтрация по "точки вызова api". Совершает
* прерывание запроса по истчению таймаута. Автоматически устанавливает токен и заголовки, контролирует работу с api
* предотвращая обращения к несуществующим url на этапе транспиляции.
*
* Для выполнения запросов использует конфигурационный файл. В конфигурационном файле указывается домен с которым
* должен работать API и список доступных ссылок(роутов), а так же другие параметры.
*
* Архитектура:
* 1. В основе модуля лежит идея - сервис получения данных, например данных о погоде, должен только получать данные, но
* не определять из какого источника будут получены данные. т.е. идея разделения обязанностей 1. конфигурирование
* конкретного запроса и 2. конфигурирование работы с конкретным api (доменом) в целом.
* т.е. сервис получает данные по погоде, а откуда он их получит определяется в конфигурации и используя разные
* конфигурации (config файлы) один и тот же код сервиса сможет загружать данные из разных истоников нечего не зная о них.
* */
import { InjectionToken } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams } from "@angular/common/http";
import { ISApi } from './typings';
import { TokenService } from './token.service';
import { LoadingStreamService } from './loading-stream.service';
import { ErrorsStreamService } from "./errors-stream.service";
import { Observable } from "rxjs/Observable";
import 'rxjs/add/observable/of';
/**
* Мысли по поводу кеширования запросов:
*
* Что у нас есть?
* Есть метод получающий ключ по которому можно проверить значение в хранилище.
*
* У нас есть запросы которые нужно кэшировать, а есть которые нет. т.е. методы.
* GET запросы мы кэшируем. потому что мы получаем данные
* POST, PUT, PATCH запросы мы кэшировать не можем так как они изменяют данные
* итого кэшируются только GET запросы.
* Нужно иметь глобальный флаг в конфигурации cache
* а для каждого отдельно взятого запроса нужно иметь возможность
* в конфиге опциях запроса нужно учесть флаг освежения запроса. если он true то в любом случае выполнить http запрос
*
* Нужно поработать с объектом типа storage. Создать ему еидный интерфей. продумать переключение между разными
* хранилищами.
*
* У нас много хранилищь и конфигураций. При декларировании провайдера мы должны определить как именно будет создаваться
* экземпляр класса ApiService и сделать это таким образом, чтоб эземпляру были переданы все нужные конфигурации путей
* http и все возможные типы хранилищь из которых api.service сможет доставать данные.
* Для обращения к хранилищу используем метод lookInStorage который посмотрит в конфигурации имя хранилища к которому
* нужно обратиться за данными и выполнит обращение. Полученные данные вернет наружу.
*
* Если мы кэшируем какой лиюо get запрос то может возникнуть ситуация когда POST запросом или PATCH запросом данные
* были изменены. В данной ситуации в кэше окажутся устаревшие данные. Нужно предусмотреть стратегию которая решит
* данную проблему.
* */
export declare const API_CONFIG: InjectionToken<{}>;
export declare const API_SERVICE: InjectionToken<{}>;
export declare class ApiService {
private http;
private token;
private errors;
private loading;
apiConfigs: any;
protected _defaultField: string;
storages: ISApi.storages;
configs: ISApi.configs;
constructor(http: HttpClient, token: TokenService, errors: ErrorsStreamService, loading: LoadingStreamService, apiConfigs: any);
/**
* @desc - получить конфигурацию по имени
* */
getConfig<T>(name: string): T;
/**
* @desc - Задает конфигурацию которая будет использована для выполнения http запроса. Любой http запрос начинается с
* этого метода.
* */
useConfig<T>(name: string): {
request: (cb: (config: T) => ISApi.apiRequestOptions<HttpHeaders, HttpParams>) => {
stream: <T>() => Observable<T>;
promise: <T>() => Promise<T>;
};
};
/**
* @desc - конфигурирует http запрос. устанавливает url, заголовки, токен параметры и т.д.
* */
private request2(apiOptions);
/**
* @desc - определяет какой метод (get, post и т.д.) нужно вызывать исходя из конфигурации
* */
private doRequest(apiOptions);
/**
* @desc - навешивает на http запрос функции общие для любого запроса. Генерация потока ошибок, потока загрузок
* и таймаут запроса. Сюда можно добавить кэширование, повторные запросы при неудаче и др.
* */
private getStartLoadingWrapper(request, apiOptions);
/**
* @desc - закодирует параметры get запроса. !!знак '+' нужно кодировать отдельно иначе возникнет ошибка!!
* */
private encodeURL(url, paramsArray, config);
/**
* @desc - проверяет уловия при которых можно отдавать закэшированное значение и если уловия верны возвращает кэш.
* */
private checkConditionsAndGetCache(apiOptions);
/**
* @desc - Для обращения к хранилищу используем метод lookInStorage который посмотрит в конфигурации имя хранилища
* к которому нужно обратиться за данными и выполнит обращение. Полученные данные вернет наружу.
* */
private lookInStorage(key, storage?);
/**
* @desc - Используя базовый url и набор GET параметров запроса формирует имя ключа для сохранения и получения
* закэшированных данных для данного url.
* */
private getKey<T>(baseURL, params, exclude?);
}