vendredi 4 juin 2021

How should i design a shared service module in a large angular project?

we are developing a huge project consisting of dozens of modules and hundreds of links in the company i work for now. i have problems in terms of design. there are too many service requests in the application. i am considering moving all services to one shared service. in this way, anyone can use services by calling a single class, and this is a more readable structure. structure and file directory structure i created looks like this.

file structure

shared/
  - services/
    - shared-services/
      - module-interface/
        - module1.interface.ts
        - module2.interface.ts
          ...
      - AllServiceRoutes.ts
      - SharedModule.service.ts
    -SharedService.ts
  - sharedModule.module.ts

i defined files in the module-interface directory as interfaces.

module1.interface.ts and others

export interface Module1Interface {
   getFtpIn(options?: {id : string }): Observable<FtpInResponseModel[]>;

   getFtpOut(options?: {id : string }): Observable<FtpOutResponseModel[]>; 
   ...
}

in the AllServiceRoutes.ts file, i wrote all RESTFul request urls in the application.

in AllServiceRoutes.ts

export class AllServiceRoutes {
  public static getFtpInURL(): string  { return `path/to/ftpin/service` };
  public static getFtpOutURL(): string  { return `path/to/ftout/service` };
  ...
}

finally, i merge the whole list of interfaces and routes into SharedModule.service.ts.

in SharedModule.service.ts

import {AllServiceRoutes} from './AllServiceRoutes';
import {Module1Interface} from "./module-interface/module1.interface";
import {Module2Interface} from "./module-interface/module2.interface";
import {ApiService} from '@shared/ApiService';

export class SharedModuleService extends ApiService implements Module1Interface, Module2Interface,.. {

 public getFtpIn(options?: {id : string }): Observable<FtpInResponseModel[]> {
    return super.get(AllServiceRoutes.getFtpInURL(), options);
  }

  public getFtpOut(options?: {id : string }): Observable<FtpOutResponseModel[]> {
    return super.get(AllServiceRoutes.getFtpOutURL(), options);
  }
  ...
}

here, ApiService.ts is also involved. this module acts as helper for us and makes necessary configurations by editing links given as parameters and requests http.get. here is content.

Note: the super.get method references the get method in ApiService.ts.

ApiService.ts

export class ApiService {
 constructor(private http: HttpClient, private config : ConfigHelper) {}

 public get(url: string, options?: any): Observable<any[]> {
    let q : Observable<HttpEvent<Object>> = this.http;
    if (typeof options !== 'undefined') {
      if (options.cache) {
        q = q.cache();
      }

      if (options.disableCheck) {
        q = q.disableCheckResponse();
      } 
    }
    return q.get<any[]>(this.apiUrl(url, options);
  }

  private apiUrl(url :string, options : any) :string {
    // added configuration and makes api url
    return url; 
  }

}

let's continue, since i use implements in SharedModuleService class, i need to create all interfaces.

finally i am moving SharedModuleService class into SharedService now

SharedService.ts

@Injectable()
export class SharedService extends SharedModuleService {}

by providing the SharedService class in shared.module.ts, i can now use it in whole application.

in shared.module.ts

@NgModule({
  ...
  providers: [SharedService],
  ...
})
export class SharedModule {
  static forRoot(): ModuleWithProviders<SharedModule> {
    return {
      ngModule: SharedModule,
      providers: []
    };
  }
}

this build is currently working. i can easily access all api requests. but i have some questions. i will be very pleased if those who have experienced answers.

  1. is this structure correct and conforms to software rules?
  2. is there a method i doing wrong in software design?
  3. is it okay to call constant string expressions this way in AllServiceRoutes.ts? should javascript garbage collector destroy them? or should i keep it in a local variable?
  4. SharedModuleService class had too many lines after making all interface implementations and code was less readable. is there different method?
  5. Do you have any extra advice?

it was very long question, i tried to be completely descriptive. i apologize in advance for my bad english i got help from google translate where stuck.

Aucun commentaire:

Enregistrer un commentaire