Repository Pattern
Abstract data access behind an interface so your business logic never knows whether data comes from a database, cache, or API — and testing becomes a one-liner swap.
Why this matters
When a service directly imports a database driver or fires raw SQL, the business rule and the storage plumbing are fused. You can't test the rule without a real database, you can't swap Postgres for Redis without rewriting the service, and every storage detail bleeds into the domain. The Repository pattern draws a clean line: define an interface that describes what the domain needs (find pending orders, save an order), then provide separate implementations for production storage and in-memory testing. The domain never imports a driver again.
Testing becomes trivial
With a repository interface in place, a complete unit test for OrderService needs no database, no network, no docker-compose. Inject an InMemoryOrderRepository, seed it with test data, and verify results — the test runs in milliseconds and never flakes. In production, inject PostgresOrderRepository via your DI container. Same service, zero changes.
💡Key takeaway
Repository hides the plumbing. Your domain speaks to an interface — swapping Postgres for in-memory, Redis, or a remote API is a one-liner in the DI wiring, not a rewrite of business logic.
🔧 Some exercises may still have errors. If something seems wrong, use the Feedback button (bottom-right of the page) to report it — it helps us fix it fast.
Hint: If your service imports a database driver or HTTP client, the domain is leaking into infrastructure. Define an interface, inject it, and watch the test suite become trivial.
✗ Your version