Skillversitas

Mounting Sub-Applications

A FastAPI app is an ASGI application, and ASGI apps can be nested: app.mount attaches another app under a URL prefix. This is how you split a monolith into independently developed modules, or add a completely different framework (Flask, a static site, a GraphQL endpoint) to the same server.

Mounting a Second FastAPI App

from fastapi import FastAPI

# module: orders_app.py
orders_app = FastAPI()

@orders_app.get("/")
def orders_root():
    return {"service": "orders"}

@orders_app.get("/items/{item_id}")
def read_order(item_id: int):
    return {"order": item_id}
# main.py
from fastapi import FastAPI
from orders_app import orders_app

app = FastAPI()
app.mount("/orders", orders_app, name="orders")

@app.get("/")
def root():
    return {"main": True, "orders": "/orders"}

Now /orders/ and /orders/items/42 are served by the sub-app, with its own routes, middleware, and (if enabled) its own /docs at /orders/docs.

Why Mount?

  • Modularity: teams own separate FastAPI apps with separate test suites; the main app just mounts them.
  • Isolation: each sub-app can have its own middleware, exception handlers, and OpenAPI settings.
  • Deployment: in production you can split the mounts into separate services behind a proxy, or keep them in one process.

Middleware and Exceptions

Middleware added on the main app wraps the mounted app (requests pass through main-app middleware first). Exception handlers defined on the sub-app catch errors raised inside it; handlers on the main app catch everything else.

Mounting Static Content the Same Way

app.mount("/static", StaticFiles(...)) is the same mechanism - StaticFiles is just another ASGI app. The pattern generalizes: anything ASGI can be mounted.

Summary

Use app.mount("/prefix", sub_app, name="...") to nest a FastAPI (or any ASGI) app under a URL prefix. You get independent route namespaces, middleware, and docs per module, with the option to later split modules into separate deployed services without changing client URLs.