Angular Architecture - Abstraction layers
Tags: angular, webdev, architecture, frontend
Published: 2023-05-05 15:26:17


{% embed https://dev.to/digitaldino/angular-architecture-39no %}

Now that we have explored how modular design can be achieved in a standalone Angular application, let's take a closer look at how our application operates and functions by examining it through the lens of **abstraction layers**.

## Abstraction Layers

The concept behind this pattern is to divide the application into discrete layers and establish communication protocols between them.

The pattern aims to split the application into three distinct layers, namely:

- Core Layer
- Abstraction Layer
- Presentation Layer


![abstraction layers data flow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bdgab5qnnpsz3w6z0tm0.png)

---------

### Core Layer

{% embed https://dev.to/digitaldino/angular-architecture-core-module-dn4 %}

The **Core Layer** is the central implementation hub for the core application logic, including all data manipulation and external communication. This layer also includes essential business logic, such as API calls for data retrieval.

It's main parts are services for making API calls and/or state management which in case of Angular could be NgRx, NgXs, custom implementation using Subjects or other.

- **API Services** have sole purpose to facilitate communication with API endpoints and nothing more.


![Movie Service](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2wf7nybyj72seg9mt4v0.png)
<figcaption>Movie Service example used only for defining API calls</figcaption>

- **State Management Solution** serves as a centralized, immutable data store for the application. By incorporating an Abstraction Layer, we can render our components independent of both the State Management Solution and API/Data Services. This approach makes it much easier to migrate to other data management solutions in the future, as we won't need to modify the Presentational Layer (i.e., the Components).


![state management](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m7jrt6h6asl0avq9eowz.png)
<figcaption>Movie State example using Ngxs</figcaption>


![hr](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p2xe9kuogtn0ee8zcobn.png)

### Abstraction layer

The abstraction layer sits between the presentation and the core layer and handles communication between them.
Since, the goal is not to inject API and state providers directly in the presentation layer, rather, we can inject the facade service and use it to interact with the core layer.  

So abstraction layer:
- is implemented as Angular providers/services named facades _(example: movies.facade.ts)_
- exposes streams of state and interface
- is used to store and dispatch actions, observable emissions and expose observables and signals for components to use.

![Movies facade](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j49miq1glqnbwb8aeh9n.png)
<figcaption>Movies Facade - exports observables, subscribes to store and dispatches store actions </figcaption>


![hr](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p2xe9kuogtn0ee8zcobn.png)

### Presentation layer

The presentation layer (UI) layer is where all Angular components reside. Its primary responsibility is to present the application's UI and delegate user actions to the core layer through the abstraction layer. 

Inside of presentation layer we have:

**Smart/container** components:

- can pass data down to dumb components
- have facade/s and other services injected
- communicate with core layer through facades
- react to events from dumb components
- are usually page components (meaning they are routable but it is not case)


![Smart components](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5yqzq3rjs4xooepdn58v.png)
<figcaption>Movies Page smart component - injects facade and knows about the state</figcaption>


{% embed https://dev.to/digitaldino/angular-architecture-page-modules-4f7m %}

**Dumb/presentational** components:
- recieve their data through @Input() and pass events and data through @Output()
- do not contain any application logic
- mostly kept in SharedModule or at specific module components folder

![Dumb component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pvyjn2d3qlzbyyod14ev.png)
<figcaption>Movie Card presentational component - used only to show data passed from parent component</figcaption>

{% embed https://dev.to/digitaldino/angular-architecture-shared-module-1mf4 %}

![hr](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p2xe9kuogtn0ee8zcobn.png)


![Example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qtjeogg40fiv6qv9wrpo.png)
<figcaption></figcaption>


**References:**

- [dev-academy.com/angular-architecture](https://dev-academy.com/angular-architecture-best-practices/)

- [medium.com/@getrohith.sathya](https://medium.com/@getrohith.sathya/architecting-enterprise-angular-application-3276ac496c02)

- [blog.brecht.io/scalable-angular2](https://blog.brecht.io/A-scalable-angular2-architecture/)