Clean architecture with Next.js

1) Introduction and Clean architecture

Software architecture often depends on many things, but there are still some concepts and good practices, that is worth to be familiar with and consider when starting a new project.

The key concepts of…


This content originally appeared on DEV Community and was authored by Daniel Malek

1) Introduction and Clean architecture

Software architecture often depends on many things, but there are still some concepts and good practices, that is worth to be familiar with and consider when starting a new project.

The key concepts of Clean Architecture are:
Separation of Concerns: Different parts of the application handle distinct responsibilities, making the code base easier to understand and modify.
Dependency Rule: Inner layers should not depend on outer layers. This promotes loose coupling and high cohesion.
Testability: The architecture facilitates thorough unit testing by isolating components.

In this article I will show how to implement clean architecture using NextJS framework.
I have created a basic Calendar app to show how you can shape a project, check it on github.

 

2) Layers

From technical point of view the idea is based on dividing application into layers and connect them with a bunch of adapters, repository pattern and dependency inversion. Further, I will describe each part with code examples.

Image description

 

3) Entities and Use Cases

Core business logic can stay in one place, framework independent and well tested. Does it sound good? You can achieve it by utilizing Entities and Use Cases. Database may change, framework may change, but core logic will remain independent in one place. What happen when new business requirements arrive? Just edit proper Use Case.

In the example of the Calendar App I provided, use case examples seems way simple (even ICalendarEvent entity is as simple as interface), but their business logic might be extended by adding such features as:

Date and time consistency: Verify that start time precedes end time.
Event duration limits: Define minimum and maximum event durations.
Conflict detection: Check for overlapping events based on event times and locations.
Capacity limits: Enforce attendance restrictions for events.
Category-based filtering: Implement filtering events based on categories.

Remember:

  • Keep use cases focused on a single responsibility.
  • Prioritize business logic over technical implementation details.
  • Write clear and concise code for maintainability.
  • Test your use cases to ensure correct behavior.

 

4) Controllers, Presenters and Dependency inversion

Image description

Controller captures an event that takes place in application, invokes a use case and, if needed, passes output from use case to presenter to map data and make it fit to an UI.

Image description

Controller is a place which connects the outside world with the application's core logic. What is very important to mention here, it also utilizes dependency inversion principle. According to this principle use cases should not depend on outer layers. Advantage of dependency inversion principle are:

Improved maintainability: Changes in the underlying implementation (e.g., database) have minimal impact on the use cases.
Better code organization: Clear separation of concerns between business logic and technical details.
Enhanced flexibility: You can easily swap out different implementations of dependencies without affecting the core use cases.
Increased testability: By isolating use cases from external dependencies, you can easily write unit tests without relying on complex setups.

In Calendar App that I have provided, you can see exactly that for example when deleting calendar event, deleteEventUseCase is invoked with repository and output of the use case is used to refresh the view. Controllers that I have made receive many arguments, which make them hard to maintain. That might be improved in several ways, for example by using some external JavaScript dependency inversion library or creating your own system for that. A simple improvement in the Calendar Application might be made by creating a hooks controllers, which will encapsulate state and interaction methods and return them:

useCalendarViewController:

export function useCalendarViewController(
  repository: IRepository,
) {
  const [calendarViewData, setCalendarViewData] = useState<TCalendarView | null>(null);

  // const nextCalendarView = async () => {
  // const prevCalendarView = async () => {
  // const fetchCalendarEventData = async (
  // const searchCalendarEvent = async (


  return { calendarViewData, nextCalendarView, prevCalendarView, fetchCalendarEventData, searchCalendarEvent }
}

CalendarViewComponent:

const { calendarViewData, nextCalendarView, prevCalendarView, fetchCalendarEventData, searchCalendarEvent } =  useCalendarViewController(repository);

 

5) Outer layer and Repository pattern

In Clean Architecture, the outer layer is the furthest from the core business logic. It's where all the implementation details reside. This layer is often referred to as the Frameworks and Drivers Layer.

In the Calendar App, you can see that React components are yet another layer, it relays on data and abstraction provided by inner layers. Repository with database implementation details is also passed from here. What is advantage of using repository pattern? At any time you can change database (for example from mongodb to mysql, but also some code details) without touching core business logic, as long as interface fits.

 

6) Summary

We went through the crucial parts of clean architecture. It provides good practices for setting up your project and it is definitely worth considering especially if you know that the project will grow medium or bigger size. For compact projects using all the rules might lead to increased boilerplate code or redundant complexity in the project structure.


This content originally appeared on DEV Community and was authored by Daniel Malek


Print Share Comment Cite Upload Translate Updates
APA

Daniel Malek | Sciencx (2024-08-05T18:38:07+00:00) Clean architecture with Next.js. Retrieved from https://www.scien.cx/2024/08/05/clean-architecture-with-next-js/

MLA
" » Clean architecture with Next.js." Daniel Malek | Sciencx - Monday August 5, 2024, https://www.scien.cx/2024/08/05/clean-architecture-with-next-js/
HARVARD
Daniel Malek | Sciencx Monday August 5, 2024 » Clean architecture with Next.js., viewed ,<https://www.scien.cx/2024/08/05/clean-architecture-with-next-js/>
VANCOUVER
Daniel Malek | Sciencx - » Clean architecture with Next.js. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/08/05/clean-architecture-with-next-js/
CHICAGO
" » Clean architecture with Next.js." Daniel Malek | Sciencx - Accessed . https://www.scien.cx/2024/08/05/clean-architecture-with-next-js/
IEEE
" » Clean architecture with Next.js." Daniel Malek | Sciencx [Online]. Available: https://www.scien.cx/2024/08/05/clean-architecture-with-next-js/. [Accessed: ]
rf:citation
» Clean architecture with Next.js | Daniel Malek | Sciencx | https://www.scien.cx/2024/08/05/clean-architecture-with-next-js/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.