Welcome back! In the previous lesson, you learned how to modularize your Flask application using Blueprints. This helped you organize your controllers and maintain clean, modular code. Today, we will introduce another important concept that will further help in organizing your Flask application: the service layer.
A service layer is a design pattern used to abstract and encapsulate the business logic of an application. This separation ensures that your controllers remain clean and focused solely on handling HTTP requests and responses, while the service layer handles the actual logic and data processing.
By the end of this lesson, you will be able to create and use a service layer within your Flask application, helping you maintain a more manageable codebase.
In the Model-View-Controller (MVC) pattern, the service layer sits between the Controller and the parts of your code that interact with your data (the Model). The Controller handles HTTP requests and responses, and the Model interacts with the database. The service layer acts as a middleman, taking care of the application's business logic. This means it processes data, applies business rules, and ensures the rest of the application remains organized and manageable.
Here’s an example project structure to visualize where the service layer fits in:
Plain text1app/ 2│ 3├── controllers/ 4│ └── welcome_controller.py 5│ 6├── services/ 7│ └── welcome_service.py 8│ 9├── templates/ 10│ └── welcome.html 11│ 12└── app.py
Let's start by creating a service class called WelcomeService
inside the app/services
directory, responsible for managing a list of names and providing a method to retrieve these names.
Python1class WelcomeService: 2 def __init__(self): 3 # Initialize with a predefined list of names 4 self.names = ["Alice", "Bob", "Charlie"] 5 6 # Method to return the list of names 7 def get_names(self): 8 return self.names
In the __init__
method, we initialize the WelcomeService
class with a predefined list of names. Next, the get_names
method allows us to retrieve this list of names stored in the self.names
attribute.
By placing the business logic in this class, we ensure our controller code remains clean and focused on handling HTTP requests and responses.
Next, we will integrate the WelcomeService
into our controller. This involves importing the service, creating an instance, and using it to retrieve data within the route handler. Here is how you can update the controller code in welcome_controller.py
:
Python1from flask import Blueprint, render_template 2from services.welcome_service import WelcomeService 3 4welcome_controller = Blueprint('welcome', __name__) 5 6# Create an instance of WelcomeService 7welcome_service = WelcomeService() 8 9@welcome_controller.route('/') 10def welcome(): 11 # Get the list of names from the service 12 names = welcome_service.get_names() 13 # Pass the names to the template 14 return render_template('welcome.html', names=names)
First, we import the WelcomeService
class from the services/welcome_service.py
file. Then, we create an instance of WelcomeService
named welcome_service
. Finally, in the welcome
route, we use the get_names
method from our service to retrieve the list of names and pass it to the render_template
function.
By following this approach, we separate the business logic (retrieving names) from the controller, making it more manageable and maintainable.
Now that we have the list of names available in our controller, let's pass it to a template and render each name dynamically. Here is the updated code for welcome.html
:
HTML, XML1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <title>Welcome</title> 7</head> 8<body> 9 <ul> 10 <!-- Loop through each name in the names list --> 11 {% for name in names %} 12 <li>Welcome, {{ name }}!</li> 13 {% endfor %} 14 </ul> 15</body> 16</html>
We pass the names
list from the controller to the template through the render_template
function. Using Jinja2 template syntax, we loop through each item in the names
list with {% for name in names %}
, and display each name inside a list item (<li>
).
When the route is accessed, the welcome.html
template will render each name within an <li>
element, providing a personalized welcome message for each name.
Let's take a moment to review and run the complete setup:
- Service Layer: Created a
WelcomeService
class to handle business logic (stored inapp/services/welcome_service.py
). - Controller: Updated the controller to use the service layer and pass the retrieved data to a template (stored in
app/controllers/welcome_controller.py
). - Template: Updated the template to loop through the data and render it dynamically (stored in
app/templates/welcome.html
).
To see this in action, start your Flask application and navigate to the root route (/
). You should see a list of personalized welcome messages, each rendered as a list item.
In this lesson, you learned how to use a service layer in your Flask application to separate business logic from the controllers. This helps in maintaining cleaner and more modular code. Specifically, you:
- Created a
WelcomeService
class to manage a list of names. - Integrated the service layer with a controller and a template.
- Rendered dynamic content using a loop in the template.
With this knowledge, you are now equipped to handle more complex business logic in a structured way. Up next, you will have practice exercises to reinforce what you have learned in this lesson. Keep experimenting and consider adding additional functionality to the service layer for more advanced practice.