Vadim Ferderer
โ€“ Architecture is perfect when nothing can be taken away.

Matryoshka Architecture ๐Ÿช†

One recursive pattern. Every level. From app to action.

The Problem

Spring Boot has no official guidance for package structures beyond tutorials. Existing approaches each solve part of the puzzle:

Approach Strength Weakness
Package-by-Layer Easy to start No cohesion, no encapsulation
Package-by-Feature High cohesion No answer for cross-cutting concerns
Hexagonal / Clean Strong boundaries Massive boilerplate, over-engineered
Spring Modulith Module verification No guidance for internal structure

None of them address all levels consistently. That's the gap Matryoshka fills.

The Solution

One recursive pattern, applied at every level:

{level}/
โ”œโ”€โ”€ config/        โ† framework setup (top-level only)
โ”œโ”€โ”€ common/        โ† shared code (any level)
โ””โ”€โ”€ {domain}/      โ† bounded context, use case, sub-module

App โ†’ Bounded Context โ†’ Use Case โ†’ Action โ€” same structure, all the way down.

What a Use Case Looks Like

One endpoint, one class, no service layer:

@RestController
@RequestMapping("/api/v1/policies/drafts")
@Transactional
class CreatePolicyDraft {

  record Request(String holderName, Coverage coverage) {}
  record Response(UUID id, String holderName, Status status) {}

  private final PolicyDraftRepository repo;
  private final TsidGenerator tsid;

  @PostMapping
  Response handle(@RequestBody Request req) {
      var draft = PolicyDraft.create(
          tsid.next(),
          req.holderName(),
          req.coverage()
      );
      repo.save(draft);
      return new Response(
          draft.id(),
          draft.holderName(),
          draft.status()
      );
  }
}
      

Extract a service only when a second caller appears.

Why "Matryoshka"?

Like Russian nesting dolls:

Enforcement

This isn't just documentation โ€“ it's enforceable:

Get Started

View on GitHub โ†’

Includes 23 Architecture Decision Records, arc42 documentation, and a practical ruleset.