Sunday, May 13, 2018

Angular Application Structure

Setting up application structure of application is one of the most important part of application development. Because well structured application allows to scale/grow application with less efforts, saves lot of effort in maintenance of application, allows to locate files and resources easily.

No framework forces to follow how to structure application (how to arrange files in different parts of application) , same goes for Angular 2 framework. It doesn't force developer to structure application, like how to arrange components, directives, pipes, services etc. created by developer. But angular team propose guideline one must follow for structuring application in style guide here : StyleGuide

Application Structure

Below diagram is visual presentation of structure of Angular application, which is as per the guide lines from angular team.




Application Module - It's Start point of angular application. This is first module get called when application get loaded. This module automatically get created when application created with the help of Angular-cli.
Point to note , all feature modules and core module is going to register themselves in this module.

Core Module - In angular application, It's module going to have application level singleton services (Ex. HttpInterceptor used for intercepting http request, LoggerService,  LoggedInUserService) or application level component (Ex. Navigation Bar).

Core Module have all singleton services,  so only the root AppModule  (Application Module) should import the CoreModule to make same instance of service in all modules of application. If a lazy-loaded module imports it too, lazy module will create its own instance of core module services and use that newly created instance of services instead of application level singleton services.  To avoid that problem make use of forRoot method and guard clause, code for that given below. https://angular.io/guide/singleton-services

export class CoreModule {

  constructor (@Optional() @SkipSelf() parentModule: CoreModule) {
    if (parentModule) {
      throw new Error(
        'CoreModule is already loaded. Import it in the AppModule only');
    }
  }
 
  static forRoot(): ModuleWithProviders {
    return {
      ngModule: CoreModule,
      providers: [
        LoggerService ,UserService
      ]
    };
  }
}

Shared Module - In angular application, It's module going to have all dump angular Pipes, Directives , Components, Function  etc. i.e. all who are dumb and receive input from, component which uses it.  Ex. Extended Form Validation Component (Check Here), Confirmation Model Popup, Formatting Pipes,  Validation &  Common functions used through out application, Directive used by controls etc its like utilities used in application .
Point to note, It should not going to have angular services.

Feature Modules - In angular application, Feature modules are going to have have features which is going to be provided by application.   (Ex. CustomerModule, OrdersModule, ProductsModule, ShippingModule).
This features modules also going to have shared features modules in which is going to be shared between this features module only. For Example. ProductDataService module which is going to be shared between ProductModule and OrderModule.

Module Dependency ( Flow of Services ) 

Below diagram shows dependency between modules (i.e. it shows the flow of services) discussed above.



Hows modules dependent or Service flow

Feature Modules - these modules are going to consume singleton services form Core Module (Via application module in which it registered) and shared dumb pipes, component, directives, functions from shared module.
Which means Feature modules depends on Core Module and Shared module i.e. service flow from core & shared modules to feature modules.
Important point to note here is, Service flows from top towards bottom, not from bottom to top. This means top level Core module, Application module and shared module must not consume service from feature modules.

Core Module - this module going to consume service from shared module if needed. Mostly it's doesn't need service from shared module but sometime need to access common function or formatting pipes for its component , that's why diagram has dotted line.
So service flows from shared module to core module if needed, otherwise this is independent module which provides application level singleton services and component. 

Application Module - this module is simple module just going to to have one component  to provide start point of application. It's going to consume services from Core Module and if needed consume services from shared module.

Shared Module - It's utility module. This module have all the dumb angular components, pipes , directives  and utility functions. So this module provides its services to all the modules (Application Module, Core Module, Feature Modules) in applications.
But its not going to consume service from other modules.

Conclusion
Angular framework doesn't force developer to follow discussed structure for developing application. But it's must need when application going to grow & developer wants to scale it up, and also helps in identifying different part of application in turns helps in maintaining application.

Putting component, service, pipe, directives in proper folder structure its not end of story. To make property structure developer must need to setup dependency properly between module i.e. flow of service as discussed.

Note
Above article is based on my reading on angular.io portal and structure applied in my application. Please comment if something wrong.

2 comments: