Skip to content

adagio/monolith_to_microservice_python

Repository files navigation

Monolith to Microservice Refactoring Example (Python)

This project demonstrates a refactoring pattern where a piece of functionality (saving data) within a monolithic application is extracted into a separate microservice. It uses Python, Flask, and asynchronous programming (asyncio, aiofiles, httpx).

Project Purpose

The goal is to show how to decouple functionality using interfaces and dependency injection, allowing the main application to switch between a local implementation (saving to a file directly) and a remote implementation (calling a microservice API) without changing its core logic.

Project Structure

monolith_to_microservice_python/
├── .venv/                    # Virtual environment (recommended)
├── entities/                 # Data structures (e.g., Beer dataclass)
│   ├── __init__.py
│   └── beer.py
├── interfaces/               # Abstract base classes defining contracts
│   ├── __init__.py
│   └── action_service.py     # Defines IActionService
├── implementations/          # Concrete implementations of interfaces
│   ├── __init__.py
│   ├── file_saver.py         # Saves data to a local file
│   └── http_file_saver.py    # Calls the microservice API
├── monolith_app/             # The original "monolithic" part
│   ├── __init__.py
│   ├── execute.py            # Class using the action service
│   ├── main.py               # Main script to run scenarios
│   └── logs/                 # Logs generated by the local file saver
│       └── monolith_local_log.txt
├── microservice_api/         # The extracted microservice (Flask API)
│   ├── __init__.py
│   ├── app.py                # Flask application
│   ├── requirements_api.txt  # Dependencies for the API
│   └── logs/                 # Logs generated by the API
│       └── api_log.txt
├── requirements.txt          # Dependencies for monolith & HTTP client
└── README.md                 # This file

Setup

  1. Clone the repository (if applicable)
  2. Create and activate a virtual environment:
    python -m venv .venv
    # Windows
    .\.venv\Scripts\activate
    # macOS/Linux
    source .venv/bin/activate
  3. Install dependencies for the Monolith/Client:
    pip install -r requirements.txt
  4. Install dependencies for the Microservice API:
    pip install -r microservice_api/requirements_api.txt

Running the Application

You need two terminals (or run the API in the background).

  1. Terminal 1: Run the Microservice API Navigate to the project root directory and run the Flask app using an ASGI server like Hypercorn:

    # Make sure your virtual environment is active
    # Ensure Flask[async] is installed (check requirements_api.txt)
    python -m hypercorn microservice_api.app:app --bind localhost:7183

    (Note: The port 7183 is used in the example code, matching the C# version's convention. The code in microservice_api/app.py explicitly binds to this). You should see output indicating the server is running.

  2. Terminal 2: Run the Monolith Scenarios Navigate to the project root directory and run the main script:

    # Make sure your virtual environment is active
    python -m monolith_app.main

    This script will execute two scenarios:

    • Saving data using the local FileSaver. Check monolith_app/logs/monolith_local_log.txt.
    • Saving data by calling the running microservice API via HttpFileSaver. Check microservice_api/logs/api_log.txt.

Key Concepts Demonstrated

  • Dependency Injection: The Execute class receives its dependency (IActionService) via its constructor, allowing different implementations (FileSaver, HttpFileSaver) to be injected.
  • Interfaces (Abstract Base Classes): IActionService defines a contract that concrete implementations must follow.
  • Decoupling: The monolith_app doesn't need to know the details of how the action is performed, only that it conforms to the IActionService interface.
  • Asynchronous Operations: Uses async/await for file I/O (aiofiles) and HTTP requests (httpx) to avoid blocking.
  • Microservice API: A simple Flask API provides the saving functionality over HTTP.

About

Monolith to Microservice Refactoring Example (Python)

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages