Lesson 5
Managing Business Logic with Service Layer
Managing Business Logic with Service Layer

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.

Understanding the Service Layer

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 text
1app/ 23├── controllers/ 4│ └── welcome_controller.py 56├── services/ 7│ └── welcome_service.py 89├── templates/ 10│ └── welcome.html 1112└── app.py
Creating the WelcomeService Class

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.

Python
1class 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.

Integrating WelcomeService in the Controller

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:

Python
1from 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.

Looping Through Items in a Template

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, XML
1<!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.

Putting It All Together

Let's take a moment to review and run the complete setup:

  1. Service Layer: Created a WelcomeService class to handle business logic (stored in app/services/welcome_service.py).
  2. Controller: Updated the controller to use the service layer and pass the retrieved data to a template (stored in app/controllers/welcome_controller.py).
  3. 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.

Summary and Next Steps

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.

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.