The purpose of this project was to practice working with clean code principles. This project that implements Hexagonal Architecture using Typescript and NodeJS. The project utilizes Express, Fastify, and TypeORM as frameworks and tools to manage HTTP requests and database interactions on the edge layer.
The Hexagonal Architecture, also known as Ports and Adapters architecture, aims to create a flexible and loosely coupled design. It achieves this by separating the core business logic (application and domain) from the external systems (databases, web frameworks, etc.). The design promotes testability, maintainability, and scalability of the application.
In this project:
- The Core contains business logic that remains decoupled from the external layers.
- The Infrastructure layer deals with the specifics of external integrations (e.g., persistence mechanisms, clients).
- The Application layer is responsible for implementing use cases and orchestrating the flow of data.
-
Entities (Domain Layer): Entities represent the core business objects of the system, such as
Item
,Order
, andPayment
. They encapsulate the business rules and logic but are free from any technical dependencies (such as web frameworks or databases).Example:
Item.ts
,Order.ts
, andPayment.ts
are entities that contain attributes and methods relevant to the system's business logic. -
Ports: Ports define interfaces that decouple the core logic from external systems or services. They act as entry (input ports) or exit (output ports) points to/from the application. These are implemented in the
application/ports/
directory for external services (e.g.,PaymentService
,CacheService
) and in thecore/ports/
directory for persistence (Repository.ts
) or external clients. -
Adapters (Infrastructure Layer): Adapters implement the details of external interactions based on the ports defined in the application or core layer. For example, adapters for data persistence (repositories using TypeORM or in-memory storage) or clients for third-party services like payment gateways.
Example:
TypeOrmItemRepository.ts
andInMemoryItemRepository.ts
are repository adapters for interacting with storage.InMemoryPaymentClient.ts
is an example of a payment client adapter.
-
Application Services (Application Layer): These services define the main use cases of the application. They act as orchestrators, interacting with the domain entities and ports to fulfill business requirements. The application services reside in the
services/
directory.Example:
ItemApplicationService.ts
handles operations related toItem
such as creating, updating, or fetching items.OrderApplicationService.ts
handles order-specific business logic.
-
Controllers: Controllers are part of the edge layer and handle HTTP requests from external clients. They convert the incoming data to the format expected by the application and delegate business operations to the application services.
Example:
ItemController.ts
handles item-related HTTP routes and maps them to the corresponding application service.OrderController.ts
does the same for orders.
By default, the following in-memory implementations are used:
- InMemoryItemRepository.ts for item persistence.
- InMemoryOrderRepository.ts for order persistence.
- InMemoryPaymentClient.ts for payment processing.
These can be replaced by their TypeORM counterparts if you want to integrate a real database.
Make sure you have Docker and Docker-Compose installed for running the infrastructure services (e.g., databases).
Install all dependencies by running:
npm install
You can run the application using either Express or Fastify.
npm run start:express
npm run start:fastify
To start the necessary infrastructure using Docker, you can run:
docker-compose up -d
The project includes unit tests for core services. You can run the tests with:
npm run test
Erick Gonzalez | eg180 - Restructuring for clean code principles, Include implentation for Orders service, expand test coverage
This project is a fork of Hexagonal Architecture Example, created by guilhermegarcia86.
Significant changes have been made to better align with clean code principles, including project restructuring, implementation for Orders service, and expanding test coverage.