Loading course…
Loading course…
Created by Petter Smit
Design backends that stay modular as they grow: clear layers, stable interfaces, and dependency direction that keeps changes local. You’ll practice applying ports/adapters and dependency injection, making data access swappable, defining API contracts with validation, and choosing tests that protect reuse—then packaging modules for reuse across projects.
8 modules • Each builds on the previous one
Learn how to slice a backend into modules by responsibility (domain logic, application services, infrastructure, delivery/API) so changes stay local and reuse stays realistic.
Design module APIs (function/class interfaces) that stay stable while implementations change—using explicit contracts, narrow interfaces, and clear input/output models.
Apply Dependency Inversion Principle (DIP) so business logic depends on abstractions (ports), while infrastructure (databases, email, queues) plugs in via adapters.
Use dependency injection (constructor injection, factories, lightweight DI patterns) to wire modules together without hard-coding implementations—making code reusable and testable.
Decouple domain/application logic from persistence by using repositories (and optionally Unit of Work) so you can swap databases, ORMs, or storage strategies without rewriting core code.
Design backend APIs as stable contracts using schemas (OpenAPI/JSON Schema), input validation, and versioning strategies so clients and internal modules can evolve safely.
Build confidence in reuse with a testing pyramid: fast unit tests for core logic, integration tests for adapters, and contract tests for APIs and ports.
Turn internal modules into reusable packages (shared libraries or internal packages), with semantic versioning, changelogs, and minimal public APIs so multiple projects can safely depend on them.
Begin your learning journey
In-video quizzes and scaffolded content to maximize retention.