Build a BFF (Backend for Frontend) Mock Aggregator in Python

A minimal HTTP server implementing the BFF pattern that aggregates user data and orders from two mock backends into a single JSON response.

Medium Python 3.9+ Aug 9, 2026 System design patterns 17 views 0 copies

Python code

42 lines
Python 3.9+
import json
from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import urlparse


class MockBackendA:
    def get_user(self, user_id):
        return {"id": user_id, "name": "Alice", "service": "backend-a"}


class MockBackendB:
    def get_orders(self, user_id):
        return [
            {"id": 1, "user_id": user_id, "item": "Laptop", "service": "backend-b"},
            {"id": 2, "user_id": user_id, "item": "Mouse", "service": "backend-b"},
        ]


class BFFHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        path = urlparse(self.path).path
        if path.startswith("/api/user/"):
            user_id = int(path.split("/")[-1])
            backend_a = MockBackendA()
            backend_b = MockBackendB()
            response = {
                "user": backend_a.get_user(user_id),
                "orders": backend_b.get_orders(user_id),
            }
            self.send_response(200)
            self.send_header("Content-Type", "application/json")
            self.end_headers()
            self.wfile.write(json.dumps(response).encode("utf-8"))
        else:
            self.send_response(404)
            self.end_headers()


if __name__ == "__main__":
    server = HTTPServer(("localhost", 8000), BFFHandler)
    print("BFF running on http://localhost:8000/api/user/1")
    server.serve_forever()

Output

stdout
BFF running on http://localhost:8000/api/user/1

GET http://localhost:8000/api/user/1
{
  "user": {
    "id": 1,
    "name": "Alice",
    "service": "backend-a"
  },
  "orders": [
    {
      "id": 1,
      "user_id": 1,
      "item": "Laptop",
      "service": "backend-b"
    },
    {
      "id": 2,
      "user_id": 1,
      "item": "Mouse",
      "service": "backend-b"
    }
  ]
}

How it works

This code demonstrates the Backend for Frontend (BFF) pattern using Python's standard http.server module. The BFFHandler routes incoming GET requests and, for URLs under /api/user/, extracts the user ID and calls two mock backend classes to fetch user and order data. Both responses are then merged into a single JSON object and returned to the client. This reduces the number of round trips a frontend must make and centralizes API orchestration logic.

Common mistakes

  • Forgetting to parse the URL and using the raw query string instead of the path.
  • Not handling non-integer user IDs, which causes a ValueError instead of a clean 400 response.
  • Assuming `self.path` doesn't contain query parameters when checking with `startswith`.

Variations

  1. Use `http.client` or `requests` to call real external backends instead of mock classes.
  2. Implement async aggregation with `asyncio` and `aiohttp` for concurrent backend calls.

Real-world use cases

  • A mobile app's API gateway that combines user profile and last orders into one request to save battery and reduce latency.
  • A dashboard frontend that needs aggregated stats from multiple microservices without exposing internal service URLs.
  • A BFF layer that filters sensitive fields from backend responses before sending them to the browser.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from System design patterns

Related tutorials and quizzes for this topic.