Service-repository pattern
Overview
The Service-Repository pattern splits your logic layer and data layer into two specific roles. The **Service** handles the business rules, while the **Repository** handles saving and finding data. ```python # Repository: Only talks to the database class UserRepository: def save(self, user): print(f'Saved {user} to DB') # Service: Only handles business rules class UserService: def __init__(self, repo): self.repo = repo def create_user(self, name): if len(name) < 3: return 'Name too short' self.repo.save(name) return 'Success' ``` The rule: **Services make decisions, Repositories fetch data.** Think of the Service as a manager making decisions, and the Repository as a filing clerk who only retrieves or stores folders when asked.
It makes testing much easier. You can test the Service's rules without needing a real database by giving it a fake Repository.
Where used: Domain-Driven Design (DDD), Large web applications
Why learn this
- It is the industry standard for writing maintainable backend code.
- It allows you to switch databases easily in the future without changing business logic.
Code walkthrough
class FakeRepo:
def get(self): return 'fake data'
class Service:
def run(self, repo):
data = repo.get()
return data.upper()
print(Service().run(FakeRepo()))
Focus: data = repo.get()
Common mistakes
- Putting logic in the Repository: Checking if a user's name is long enough inside the repository. The repository should be dumb; it just saves data.
- Writing SQL in the Service: Writing database queries directly in the service class. The service should call `repo.get_user()` instead.
Recall questions
- Explain the Service-Repository pattern in your own words, as if to a classmate.
- Why is it bad to put business logic inside the Repository?
- How does this pattern help with testing?
Understanding checks
What does this print?
DB saved apple
The Service calls the `save` method on the Repository object it was given, which returns the string.
If we want to change our app from a SQL database to a MongoDB database, which class do we rewrite?
The Repository.
Because the Repository handles all data storage. The Service does not know or care what type of database is used.
Practice tasks
Move logic out of the repo
Modify this code so the age check (business logic) happens in the Service, not the Repository.
Continue learning
Previous: Layered architecture