samedi 7 octobre 2023

How to refactor these Nest.js lines using high abstraction

I want to refactor these lines. Any advice would be appreciated. The MondayController and ZohoController are almost same. The MondayService and ZohoSerivce have almost same interface. But these two services have different implementations. I got stuck refactoring these lines of code.

I think SOLID principle, KISS and DRY principles should be applied here.

@Controller('monday')
export class MondayController {
  constructor(private readonly mondayService: MondayService) {}

  
  @Get()
  async getPortals(@AuthContext() { user }: Passport) {
    return this.mondayService.getPortals(user.id);
  }

  @Get('projects/all')
  @UseGuards(IsAuth)
  async getAllProjects(@AuthContext() { user }: Passport) {
    return this.mondayService.getAllProjects(user.id);
  }
}

@Controller('zoho')
export class ZohoController {
  constructor(private readonly zohoService: ZohoService) {}

  @Get()
  async getPortals(@AuthContext() { user }: Passport) {
    return this.zohoService.getPortals(user.id);
  }

  @Get('projects/all')
  @UseGuards(IsAuth)
  async getAllProjects(@AuthContext() { user }: Passport) {
    return this.zohoService.getAllProjects(user.id);
}


@Injectable()
@UseGuards(IsAuth)
export class ZohoService {
  private readonly baseUrl = 'https://projectsapi.zoho.com.location/restapi';

  constructor(
    @Inject(forwardRef(() => ZohoAuthService))
    private readonly zohoAuthService: ZohoAuthService,
  ) {}


  async getPortals(userId: string): Promise<AxiosResponse<any>> {
    const MAX_RETRY = 2;
    let retryCount = 0;
    ... content A
 }
}

@Injectable()
@UseGuards(IsAuth)
export class MondayService {

  constructor(
    @Inject(forwardRef(() => MondayAuthService))
    private readonly mondayAuthService: MondayAuthService,
  ) {}

  async getPortals(userId: string): Promise<AxiosResponse<any>> {
    const MAX_RETRY = 2;
    let retryCount = 0;
    ... content B
  }
}

I tried to define BaseService, implement MondayService and ZohoService implementing it.

import { AxiosResponse } from 'axios';
import { User } from '../../user/entities/user.entity';

export interface BaseService {
  getTasks(userId: string, projectId: string, portalId: string): Promise<any>;

  getProjects(userId: string, portalId: any): Promise<any[]>;

}

import { IntegrationPlatforms } from "../../platform-integrations/domain/integration-platforms.enum";
import { ZohoService } from "./zoho.service";
import { BaseService } from "./base.service";
import { MondayService } from "./monday.service";
import { Injectable } from "@nestjs/common";

@Injectable()
export class IntegrationFactory {
  private static services: Map<IntegrationPlatforms, BaseService> = new Map<IntegrationPlatforms, BaseService>;
  
  constructor(zohoService: ZohoService, mondayService: MondayService) {
    if (!IntegrationFactory.services) {
        IntegrationFactory.services = new Map<IntegrationPlatforms, BaseService>;
    }
    this.register(IntegrationPlatforms.ZOHO, zohoService);
    this.register(IntegrationPlatforms.MONDAY, mondayService);
    console.log('platform registered');
  }
  
  register(platform: IntegrationPlatforms, service: BaseService) {
    IntegrationFactory.services.set(platform, service);
  }
  
  get(platform: IntegrationPlatforms) {
    const service = IntegrationFactory.services.get(platform);
    if (!service) {
      throw Error(`${ platform } Platform Service Not Found`);
    }

    return service;
  }
}

Aucun commentaire:

Enregistrer un commentaire