Skip to content

Backend architecture

Jesús González Álvarez edited this page Jan 11, 2022 · 4 revisions

From MVC to Onion architecture

MVC

MVC architecture design Source

Model View Controller (MVC) is the most commonly used web application architecture. It solves the separation of concern as there is a separation between View (in this particular case the HTTP API responses), the Controller (on which the business logic is added) and the Model (it includes the database access).

As we can see, we reach loose coupling, but tight coupling is still present. This is because classes are still dependent on concrete dependencies.

Onion architecture

It is very similar to MVC because it keeps the separation of concerns but it solves the issue of tight coupling.

How Onion architecture solves tight coupling?

It is based on Dependency Inversion Principle. All layers communicate with each other using interfaces. Concrete implementations are resolved on runtime.

Onion architecture design Source

Layers are built on interfaces. This is also very convenient for testing purposes, due to the ease of exchanging a layer for a mock or another implementation object.

The layers can change, but the idea is that all layers are towards to center, where the Core of the application is. It represents the business and behavior objects.

LearnASL's Layers

  • Test

    It is used for testing purposes.

    • References: all other layers.
    • Dependencies: xUnit.
  • Api

    It is similar to view layer. It is the layer that will allow a client to interact with the application.

    • Reponsabilities (as directories):
      • Controllers: define all the endpoints of the application and call the correct services on each method.
      • Middleware: catch users' calls to the Api. It allow to have a global exception handling, authorization, authentication...
      • Properties: define the launch settings for the Http Server.
    • References: Core
    • Dependencies:
      • Api Rest: Asp.Net Core 5.0
      • Documentation: Swagger
  • Core

    It is the center part of the architecture. It contains the definition of all the entities of the application, both contracts for the Api communication with the clients and the entities, both model and data access entities. It also contains all the interfaces which are used to communicate between the Api layer and the Infraestructure (Other authors separate this into a new layer: service layer). This contains all the business logic and works with the data source.

    • Responsabilities (as directories):
      • Contracts: instead of sending and receiving the entities in the Api, a good approach is to use DTO (Data Transfer Objects). This way, the user don't need to send the Id before creating an entity, we can avoid to send properties that may be confidential such as passwords and we can retrieve just the needed information.
      • CustomEntities: definition of application entities, such as metadata to send information about pagination in the api, pagination entity, etc
      • Entities: definition of data access models.
      • Enums
      • Exceptions: definition of custom exceptions.
      • Extensions: helper functions to improve code readability.
      • Interfaces: interfaces for repositories and services of the app.
      • Options: implementation of options pattern.
      • QueryFilters: filters for get Api methods.
      • Services: implementation of services to control de data access.
      • ValidationAttributes: attributes to validate models.
    • References: None
    • Dependencies: None
  • Infrastructure

    Concrete implementations of all the services needed by the app to work.

    • Responsabilities (as directories):
      • Data: definition of the context and migrations.
      • Extensions: initialize all the services and dependency injection container.
      • Factories: to implement abstract factory pattern to initialize the questions.
      • Filters: add flux to validate the model in the Api.
      • Mappings: to convert an entity to a contract and reverse.
      • Migrations: database creation and updates.
      • Repositories: implementation of repositories and unit of work pattern.
      • Services: implementation of services based on external implementations. For instance: service to hash a password, send an email, create a JWT...
      • Validators: validation rules for the API filters to validate the model. For instance: email should be valid, password should have 'x' length, date should be greater than 'x'...
    • References: Core
    • Dependencies
      • Mail client: MailKit
      • ORM: Entity Framework Core
      • Validations: Fluent Validation
      • Logging: Serilog
      • Authentication: JWT
      • Mappings: automapper