Skip to content

ExplanationOfTheArchitecture

Vianney Doleans edited this page Feb 26, 2023 · 2 revisions

Explanation of the architecture

  • This wiki page give explanation about the architecture of this Blog API, the functioning, etc.
  • The explanations will be divided by section, from the lowest to the highest level of architecture.
  • Most of the architectural patterns come from DDD (Domain Driven Design).
  • I also give some feedback on the development of this API.

Level 1 : Database & Repositories

Entity Framework Core

  • The management of the database is realized by using Entity Framewok Core (EF Core).
  • Using an ORM in the context of this project enables to not be dependent to a specific database provider.
    • This project was realized with the will to be adaptable with the maximum of different environments.
  • For this reason, Entity Framewok Core (EF Core) was chosen instead of more traditional technology like ADO.NET.

DBAccess

  • DBAccess project is where SQL requests are encapsulated for database communications.
  • Repository pattern from DDD (Domain Driven Design) was used for this purpose.
    • Any access to the database can only be done from the repositories. In this way, database/SQL logic is separated from the rest of the project (and so also the business logic), which improves the robustness of the API.
    • Most of the entities have its own repository for structuring logic (except permission (same as role) and account (same as user)).
  • Unit of work pattern from DDD has been implemented to be combined with the repositories.
    • By doing this, the modifications done by the repositories can be applied or canceled in case of failed operation for example (There were only kept in the memory until then).
  • Entity Framework Core already applied repository & Unit of Work patterns from DDD in the way it works. Depsite this, I applied these patterns to the project and so encapsulate Entity Framework Core. By doing this, the database communications are really totally encapsulated and can be completely redeveloped if needed without any impact on the blog API.
    • I did it because it is a personal project. On most of company projects, it would probably be overkill to do it.
  • Specification pattern from DDD was also implemented inside this project.
    • The use of this pattern makes it possible to combine criteria in searches.
      • Example : I search articles with a title composed of "chocolate" and "dessert", and a minimum of 10 likes or an author named "Philippe Etchebest".
    • The most time consuming is to implement specification pattern and then to realize the rules. The benefit is visible later when the business logic have to be realized.
      • In the case of this blog API, specification pattern was totally overkill and incredibly time consuming for the need. This blog API is a personal project with the goal of doing things right, without taking time into account, so it wasn't a problem, but I wouldn't do it in a project that doesn't need it.

Code First

  • The database is realized by Code First approach.
    • The database is generated by executing migration scripts, scripts generated by Entity Framework Core via the project source code.
      • In this way, the database can be deployed endlessly on new environments.
      • The database always matches the code, so less risk of incompatibilities between them in production.
      • The generated migration scripts allow you to update existing databases without the risks caused by manual manipulations.
      • Obviously, this does not exclude the need to create a backup of the database beforehand for security purposes.

Level 2 : Service & DTO

Inside BlogCoreAPI project :

Service

  • The business logic of the API is inside the services of BlogCoreAPI project following DDD's service pattern.
  • Each service corresponds to a part of business logic of the Blog API.
    • The business logic is encapsulated in the API services: it is not visible from outside (including the controllers).
      • As the business logic is encapsulated and centralized, the robustness of the API increase.
  • The services are the only elements of the API that have access to the repositories seen previously in level 1 part.
    • Since services must encapsulate the business logic of the API, they also have the duty to hide the real entities coming from the database to the outside.

DTO

  • As the services are the only elements to have access to the repositories and the business logic of the API, and therefore also to the entities coming from the database, they communicate with the outside through DTO (data transfer object), a pattern allowing to give a new representation of the object.
  • By applying this pattern, services display only a part of database entities' information, according to the current context.
  • To realize transformations from DTO to entity and from entity to DTO, Automapper library was used.

Level 3 : Controller

  • Controllers are the section of the API that will allow communication from the API to clients by exposing endpoints.
  • The controllers in this project expose at least one CRUD (Create, Read, Update, Delete) for each entity most of the time (some entities don't need it).
  • The controllers do not contain any business logic.
  • Controllers communicate with services and clients via DTOs.

Cross-Level (Dependency Injection / Tests / Swagger / Git)

Dependency injection

  • The native dependency injection (DI) of .NET Core is used in this API.
    • Possible with DI to modify (refactoring) a component without having to modify code in the rest of the API.
    • Enables to develop tests for the solution, etc.

Tests

  • Tests are realized using Moq and Xunit, but also Entity Framework Core's database in memory.
  • The solution contains unit tests, integration tests and end-to-end tests.
  • Tests are executed with a temporary database generated in the memory of the machine (thanks to Entity Framework Core).
    • So do not have to corrupt the data of an existing database for the execution of the tests.
      • Tests can be run indefinitely without variation in the results.
  • Functional tests were realized as generic classes / methods to ensure the generality of the behavior between all CRUD ednpoints of the API.
    • Helpers have been developed to encapsulate API requests and so simplify the reading of the functional tests.
  • The tests respect AAA pattern (Arrange, Act, Assert).
  • Currently, the code coverage is over 80% (almost 450 tests).

Swagger

Git

  • Conventional Commits is used for the commits of this project.
  • GitFlow workflow is applied.
  • Each pull request on master branch must pass the sonarQube scan & test executions.