Home Projects Portfolio Dashboard Export PDF Log in

Structuring the dona-ana-backend: Initializing with Strapi and Hexagonal Architecture

Foundation

We have officially kicked off the development of the dona-ana-backend project. Our goal is to create a robust and maintainable API service that can grow alongside our requirements. To achieve this, we have decided to utilize Strapi as our content management foundation, wrapped in a Hexagonal Architecture pattern.

The Challenge

Starting a new project often brings the temptation to tightly couple business logic with the framework's database layer. However, we recognized two potential bottlenecks early on:

  • Framework Lock-in: Directly embedding complex business rules into Strapi controllers makes them hard to test and migrate later.
  • Scalability Concerns: As the project evolves, we want to ensure our core domain logic remains isolated from our infrastructure (database, API endpoints).

The Strategy

To address this, we are enforcing a strict separation of concerns. By adopting Hexagonal Architecture (or "Ports and Adapters"), we treat Strapi as an infrastructure adapter rather than the application core.

Here is a conceptual look at how we structure our service layers:

// Domain Layer: Pure business logic, framework-agnostic
interface UserDomain {
  id: string;
  name: string;
}

// Infrastructure Layer: The Strapi adapter
class UserStrapiAdapter {
  async findOne(id: string): Promise<UserDomain> {
    const entry = await strapi.db.query('api::user.user').findOne({ where: { id } });
    return this.mapToDomain(entry);
  }

  private mapToDomain(data: any): UserDomain {
    return { id: data.id, name: data.name };
  }
}

Key Decisions

  1. Core Domain Independence: Business rules reside in pure TypeScript modules that have no knowledge of Strapi internals.
  2. Interface Ports: We define clear interfaces for data persistence, allowing us to swap or mock database providers during unit testing.
  3. Decoupled API Layer: Strapi controllers act strictly as thin entry points that delegate calls to our service interfaces.

Results

By establishing this structure at the "Version 0" stage, we have gained:

  • Improved Testability: We can now test our business logic without spinning up the full Strapi runtime.
  • Cleaner Maintenance: Refactoring the database structure no longer requires rewriting the business services.

Lessons Learned

Building with a modular mindset from the first commit is the best investment for long-term project health. Even when using a powerful framework like Strapi, keeping your domain code isolated ensures you remain in control of your application's architecture.

Takeaway: Start your next project by defining your business domain models before hooking them into any framework-specific controllers. This simple step forces you to clarify your logic before implementation details get in the way.


Generated with Gitvlg.com

J

JoelRodriguezDEV

Author

Share: