Dirk Richter
Software-Entwicklung und Architektur
Die Entity-Falle innerhalb einer Clean Architecture
Moderne Software-Architekturen profitieren von klaren Strukturen und Schnittstellen. Das Zusammenspiel von Backend for Frontend (BFF), Domain Driven Design (DDD) und einer sauberen Onion/Clean Architecture ermöglicht es, komplexe Anforderungen zu erfüllen und die Wartbarkeit zu erhöhen. In einer typischen Architektur mit ASP.NET Core als BFF, DDD und Onion Architecture sieht der Aufbau folgendermaßen aus: Ein häufiges Problem in API-Designs ist die Entity-Falle: APIs werden oft nur als generische CRUD-Interfaces (Create, Read, Update, Delete) für Datenbank-Entities gebaut. Das klingt zunächst einfach, führt aber schnell zu Problemen: BFF und DDD lösen diese Falle, indem die API sich an den jeweiligen Usecases orientiert und die Geschäftslogik zentral im Backend verbleibt. Die Controller rufen gezielt Usecase-Handler auf, die die Domänenmodelle korrekt behandeln – statt nur rohe Entities zu bearbeiten. CRUD-API: Usecase-orientiert: Das Zusammenspiel von BFF, DDD und Clean Architecture sorgt für klare Verantwortungstrennung, bessere Wartbarkeit und eine API, die sich an den tatsächlichen Geschäftsprozessen orientiert. Die Entity-Falle wird so vermieden und die Software bleibt flexibel und fachlich korrekt.
Inhaltsverzeichnis
Einleitung
Architekturüberblick
PlantUML-Skizze
@startuml
!theme plain
actor "Frontend" as FE
package "BFF (ASP.NET Core)" {
[OrdersController]
[ProductsController]
}
package "Application Layer" {
[CreateOrderUseCase]
[GetProductListUseCase]
}
package "Domain Layer" {
[Order]
[Product]
}
package "Infrastructure Layer" {
[OrderRepository]
[ProductRepository]
}
FE --> OrdersController : HTTP Request
FE --> ProductsController : HTTP Request
OrdersController --> CreateOrderUseCase : Call Usecase
ProductsController --> GetProductListUseCase : Call Usecase
CreateOrderUseCase --> Order : Domainlogik
GetProductListUseCase --> Product : Domainlogik
CreateOrderUseCase --> OrderRepository : Persistenz
GetProductListUseCase --> ProductRepository : Persistenz
@enduml
Die Entity-Falle: Warum eine API mehr als nur CRUD sein sollte
Beispiel: Unterschied zwischen CRUD und Usecase-orientierter API
1POST /api/orders
2PUT /api/orders/{id}
3DELETE /api/orders/{id}
4GET /api/orders/{id}
1POST /api/orders/submit // Validiert und verarbeitet einen Bestellvorgang
2POST /api/orders/{id}/cancel // Führt Geschäftsregeln zur Stornierung aus
3GET /api/orders/{id}/status // Liefert Status inkl. Fachlogik
Fazit