Repository

Repositories are classes that handle data access, inspired by Repository pattern.

In web projects, data is mostly from back-end APIs.

In mobile apps, data may be stored in local database or Firebase remote config.

  1. Single instance only

    Each service should have only 1 instance object and it should be initialized right after service class declaration inside the module file. For example:

    import {Repository} from 'react3l-common';
       
     export class TestRepository extends Repository {
       public list(): Observable<Test[]> {
         return this.http.post<Test[]>(nameof(this.list), {})
           .pipe(Repository.responseMapToList<Test>(Test));
       }
     }
        
     export const testRepository: TestRepository = new TestRepository();
    
  2. No dependency injection

    Repository should contain methods to access data only.

    No side effect should be made.

    No Dependency injection needed.

  3. Domain driven design

    Each repository should refer to one business domain of your app. For example: Product, Order, Customer, …

  4. Interceptors

    Repository uses axios for API calls. Axios support interceptors to modify request before sent and response before received.

    You may use interceptors to transform your request payload and response data, capture API's exception to send to logging system (Sentry for example)

    To use intercetors, create a file in your config folder. It should be usually named repository.ts:

    import {Repository} from 'react3l-common';
    import type {AxiosRequestConfig, AxiosError, AxiosResponse} from 'axios';
       
    Repository.requestInterceptor = function (config: AxiosRequestConfig): AxiosRequestConfig {
      if (config.data instanceof FormData) {
        config.headers['Content-Type'] = 'multipart/form-data';
      } else {
         config.headers['Content-Type'] = 'application/json';
      }
         
      return config;
    }
       
    Repository.responseInterceptor = function (response: AxiosResponse): AxiosResponse {
      return response;
    }
       
    Repository.errorInterceptor = function (error: AxiosError): AxiosError {
      // error should be re-throw so it can be re-catch otherwhere.
      throw error;
    }
    

    In each repository class, import the config file like below:

    import 'src/config/repository';