[{"data":1,"prerenderedAt":867},["ShallowReactive",2],{"nav":3,"page-\u002Fcore-architecture-routing-patterns\u002Fmodular-router-organization\u002Fapirouter-prefix-vs-sub-application-mounting\u002F":310,"surround-\u002Fcore-architecture-routing-patterns\u002Fmodular-router-organization\u002Fapirouter-prefix-vs-sub-application-mounting\u002F":865},[4,96,212],{"title":5,"path":6,"stem":7,"children":8},"Advanced Pydantic Validation Serialization","\u002Fadvanced-pydantic-validation-serialization","advanced-pydantic-validation-serialization",[9,12,30,42,54,66,90],{"title":10,"path":6,"stem":11},"Advanced Pydantic Validation and Serialization","advanced-pydantic-validation-serialization\u002Findex",{"title":13,"path":14,"stem":15,"children":16},"Custom Validators and Field Constraints in Pydantic","\u002Fadvanced-pydantic-validation-serialization\u002Fcustom-validators-field-constraints","advanced-pydantic-validation-serialization\u002Fcustom-validators-field-constraints\u002Findex",[17,18,24],{"title":13,"path":14,"stem":15},{"title":19,"path":20,"stem":21,"children":22},"Creating Reusable Custom Validators in Pydantic","\u002Fadvanced-pydantic-validation-serialization\u002Fcustom-validators-field-constraints\u002Fcreating-reusable-custom-validators-in-pydantic","advanced-pydantic-validation-serialization\u002Fcustom-validators-field-constraints\u002Fcreating-reusable-custom-validators-in-pydantic\u002Findex",[23],{"title":19,"path":20,"stem":21},{"title":25,"path":26,"stem":27,"children":28},"Pydantic v2 Async Custom Validator: What to Do Instead","\u002Fadvanced-pydantic-validation-serialization\u002Fcustom-validators-field-constraints\u002Fpydantic-v2-async-custom-validator","advanced-pydantic-validation-serialization\u002Fcustom-validators-field-constraints\u002Fpydantic-v2-async-custom-validator\u002Findex",[29],{"title":25,"path":26,"stem":27},{"title":31,"path":32,"stem":33,"children":34},"JSON Schema Customization in Pydantic and FastAPI","\u002Fadvanced-pydantic-validation-serialization\u002Fjson-schema-customization","advanced-pydantic-validation-serialization\u002Fjson-schema-customization\u002Findex",[35,36],{"title":31,"path":32,"stem":33},{"title":37,"path":38,"stem":39,"children":40},"Customizing OpenAPI Schema Generation in FastAPI","\u002Fadvanced-pydantic-validation-serialization\u002Fjson-schema-customization\u002Fcustomizing-openapi-schema-generation-in-fastapi","advanced-pydantic-validation-serialization\u002Fjson-schema-customization\u002Fcustomizing-openapi-schema-generation-in-fastapi\u002Findex",[41],{"title":37,"path":38,"stem":39},{"title":43,"path":44,"stem":45,"children":46},"Nested Model Serialization in FastAPI","\u002Fadvanced-pydantic-validation-serialization\u002Fnested-model-serialization","advanced-pydantic-validation-serialization\u002Fnested-model-serialization\u002Findex",[47,48],{"title":43,"path":44,"stem":45},{"title":49,"path":50,"stem":51,"children":52},"Handling Deeply Nested JSON Models Efficiently","\u002Fadvanced-pydantic-validation-serialization\u002Fnested-model-serialization\u002Fhandling-deeply-nested-json-models-efficiently","advanced-pydantic-validation-serialization\u002Fnested-model-serialization\u002Fhandling-deeply-nested-json-models-efficiently\u002Findex",[53],{"title":49,"path":50,"stem":51},{"title":55,"path":56,"stem":57,"children":58},"Performance Optimization for Pydantic Models in FastAPI","\u002Fadvanced-pydantic-validation-serialization\u002Fperformance-optimization-for-models","advanced-pydantic-validation-serialization\u002Fperformance-optimization-for-models\u002Findex",[59,60],{"title":55,"path":56,"stem":57},{"title":61,"path":62,"stem":63,"children":64},"Pydantic Model Serialization Performance in FastAPI","\u002Fadvanced-pydantic-validation-serialization\u002Fperformance-optimization-for-models\u002Fpydantic-model-serialization-performance","advanced-pydantic-validation-serialization\u002Fperformance-optimization-for-models\u002Fpydantic-model-serialization-performance\u002Findex",[65],{"title":61,"path":62,"stem":63},{"title":67,"path":68,"stem":69,"children":70},"Pydantic V2 Migration Guide for FastAPI","\u002Fadvanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide","advanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide\u002Findex",[71,72,78,84],{"title":67,"path":68,"stem":69},{"title":73,"path":74,"stem":75,"children":76},"Migrate @validator to @field_validator in Pydantic v2","\u002Fadvanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide\u002Fmigrate-validator-to-field-validator","advanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide\u002Fmigrate-validator-to-field-validator\u002Findex",[77],{"title":73,"path":74,"stem":75},{"title":79,"path":80,"stem":81,"children":82},"Migrating from Pydantic v1 to v2 Without Breaking APIs","\u002Fadvanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide\u002Fmigrating-from-pydantic-v1-to-v2-without-breaking-apis","advanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide\u002Fmigrating-from-pydantic-v1-to-v2-without-breaking-apis\u002Findex",[83],{"title":79,"path":80,"stem":81},{"title":85,"path":86,"stem":87,"children":88},"model_config vs class Config in Pydantic v2","\u002Fadvanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide\u002Fmodel-config-vs-class-config","advanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide\u002Fmodel-config-vs-class-config\u002Findex",[89],{"title":85,"path":86,"stem":87},{"title":91,"path":92,"stem":93,"children":94},"Type Hinting and IDE Integration in FastAPI","\u002Fadvanced-pydantic-validation-serialization\u002Ftype-hinting-ide-integration","advanced-pydantic-validation-serialization\u002Ftype-hinting-ide-integration\u002Findex",[95],{"title":91,"path":92,"stem":93},{"title":97,"path":98,"stem":99,"children":100},"Async Background Tasks Observability","\u002Fasync-background-tasks-observability","async-background-tasks-observability",[101,104,122,140,158,176,194],{"title":102,"path":98,"stem":103},"Async, Background Tasks, and Observability in FastAPI","async-background-tasks-observability\u002Findex",{"title":105,"path":106,"stem":107,"children":108},"Async Correctness and Concurrency in FastAPI","\u002Fasync-background-tasks-observability\u002Fasync-correctness-concurrency","async-background-tasks-observability\u002Fasync-correctness-concurrency\u002Findex",[109,110,116],{"title":105,"path":106,"stem":107},{"title":111,"path":112,"stem":113,"children":114},"FastAPI async def vs def: Performance and When to Use Each","\u002Fasync-background-tasks-observability\u002Fasync-correctness-concurrency\u002Ffastapi-async-def-vs-def-performance","async-background-tasks-observability\u002Fasync-correctness-concurrency\u002Ffastapi-async-def-vs-def-performance\u002Findex",[115],{"title":111,"path":112,"stem":113},{"title":117,"path":118,"stem":119,"children":120},"Fixing Blocking Calls in Async FastAPI Routes","\u002Fasync-background-tasks-observability\u002Fasync-correctness-concurrency\u002Ffixing-blocking-calls-in-async-routes","async-background-tasks-observability\u002Fasync-correctness-concurrency\u002Ffixing-blocking-calls-in-async-routes\u002Findex",[121],{"title":117,"path":118,"stem":119},{"title":123,"path":124,"stem":125,"children":126},"Async Database Sessions in FastAPI","\u002Fasync-background-tasks-observability\u002Fasync-database-sessions","async-background-tasks-observability\u002Fasync-database-sessions\u002Findex",[127,128,134],{"title":123,"path":124,"stem":125},{"title":129,"path":130,"stem":131,"children":132},"Async SQLAlchemy Session per Request in FastAPI","\u002Fasync-background-tasks-observability\u002Fasync-database-sessions\u002Fasync-sqlalchemy-session-per-request","async-background-tasks-observability\u002Fasync-database-sessions\u002Fasync-sqlalchemy-session-per-request\u002Findex",[133],{"title":129,"path":130,"stem":131},{"title":135,"path":136,"stem":137,"children":138},"Fixing asyncpg Connection Pool Exhaustion in FastAPI","\u002Fasync-background-tasks-observability\u002Fasync-database-sessions\u002Ffixing-asyncpg-pool-exhaustion","async-background-tasks-observability\u002Fasync-database-sessions\u002Ffixing-asyncpg-pool-exhaustion\u002Findex",[139],{"title":135,"path":136,"stem":137},{"title":141,"path":142,"stem":143,"children":144},"Background Task Processing in FastAPI","\u002Fasync-background-tasks-observability\u002Fbackground-task-processing","async-background-tasks-observability\u002Fbackground-task-processing\u002Findex",[145,146,152],{"title":141,"path":142,"stem":143},{"title":147,"path":148,"stem":149,"children":150},"FastAPI BackgroundTasks vs Celery vs ARQ","\u002Fasync-background-tasks-observability\u002Fbackground-task-processing\u002Ffastapi-backgroundtasks-vs-celery-vs-arq","async-background-tasks-observability\u002Fbackground-task-processing\u002Ffastapi-backgroundtasks-vs-celery-vs-arq\u002Findex",[151],{"title":147,"path":148,"stem":149},{"title":153,"path":154,"stem":155,"children":156},"Running ARQ Workers with FastAPI","\u002Fasync-background-tasks-observability\u002Fbackground-task-processing\u002Frunning-arq-workers-with-fastapi","async-background-tasks-observability\u002Fbackground-task-processing\u002Frunning-arq-workers-with-fastapi\u002Findex",[157],{"title":153,"path":154,"stem":155},{"title":159,"path":160,"stem":161,"children":162},"Caching Strategies in FastAPI","\u002Fasync-background-tasks-observability\u002Fcaching-strategies","async-background-tasks-observability\u002Fcaching-strategies\u002Findex",[163,164,170],{"title":159,"path":160,"stem":161},{"title":165,"path":166,"stem":167,"children":168},"Cache Invalidation Patterns in FastAPI","\u002Fasync-background-tasks-observability\u002Fcaching-strategies\u002Fcache-invalidation-patterns-in-fastapi","async-background-tasks-observability\u002Fcaching-strategies\u002Fcache-invalidation-patterns-in-fastapi\u002Findex",[169],{"title":165,"path":166,"stem":167},{"title":171,"path":172,"stem":173,"children":174},"Redis Response Caching in FastAPI","\u002Fasync-background-tasks-observability\u002Fcaching-strategies\u002Fredis-response-caching-in-fastapi","async-background-tasks-observability\u002Fcaching-strategies\u002Fredis-response-caching-in-fastapi\u002Findex",[175],{"title":171,"path":172,"stem":173},{"title":177,"path":178,"stem":179,"children":180},"Observability and Tracing in FastAPI","\u002Fasync-background-tasks-observability\u002Fobservability-and-tracing","async-background-tasks-observability\u002Fobservability-and-tracing\u002Findex",[181,182,188],{"title":177,"path":178,"stem":179},{"title":183,"path":184,"stem":185,"children":186},"Instrumenting FastAPI with OpenTelemetry","\u002Fasync-background-tasks-observability\u002Fobservability-and-tracing\u002Finstrumenting-fastapi-with-opentelemetry","async-background-tasks-observability\u002Fobservability-and-tracing\u002Finstrumenting-fastapi-with-opentelemetry\u002Findex",[187],{"title":183,"path":184,"stem":185},{"title":189,"path":190,"stem":191,"children":192},"Structured JSON Logging with Request IDs in FastAPI","\u002Fasync-background-tasks-observability\u002Fobservability-and-tracing\u002Fstructured-json-logging-with-request-ids","async-background-tasks-observability\u002Fobservability-and-tracing\u002Fstructured-json-logging-with-request-ids\u002Findex",[193],{"title":189,"path":190,"stem":191},{"title":195,"path":196,"stem":197,"children":198},"Rate Limiting and Throttling in FastAPI","\u002Fasync-background-tasks-observability\u002Frate-limiting-throttling","async-background-tasks-observability\u002Frate-limiting-throttling\u002Findex",[199,200,206],{"title":195,"path":196,"stem":197},{"title":201,"path":202,"stem":203,"children":204},"FastAPI Rate Limiting with Redis and SlowAPI","\u002Fasync-background-tasks-observability\u002Frate-limiting-throttling\u002Ffastapi-rate-limiting-with-redis-slowapi","async-background-tasks-observability\u002Frate-limiting-throttling\u002Ffastapi-rate-limiting-with-redis-slowapi\u002Findex",[205],{"title":201,"path":202,"stem":203},{"title":207,"path":208,"stem":209,"children":210},"Per-User Token Bucket Throttling in FastAPI","\u002Fasync-background-tasks-observability\u002Frate-limiting-throttling\u002Fper-user-token-bucket-throttling","async-background-tasks-observability\u002Frate-limiting-throttling\u002Fper-user-token-bucket-throttling\u002Findex",[211],{"title":207,"path":208,"stem":209},{"title":213,"path":214,"stem":215,"children":216},"Core Architecture Routing Patterns","\u002Fcore-architecture-routing-patterns","core-architecture-routing-patterns",[217,220,232,250,268,280,292],{"title":218,"path":214,"stem":219},"FastAPI Core Architecture and Routing Patterns","core-architecture-routing-patterns\u002Findex",{"title":221,"path":222,"stem":223,"children":224},"Application Factory Patterns in FastAPI","\u002Fcore-architecture-routing-patterns\u002Fapplication-factory-patterns","core-architecture-routing-patterns\u002Fapplication-factory-patterns\u002Findex",[225,226],{"title":221,"path":222,"stem":223},{"title":227,"path":228,"stem":229,"children":230},"FastAPI App Factory Pattern for Testing and Deployment","\u002Fcore-architecture-routing-patterns\u002Fapplication-factory-patterns\u002Ffastapi-app-factory-pattern-for-testing-and-deployment","core-architecture-routing-patterns\u002Fapplication-factory-patterns\u002Ffastapi-app-factory-pattern-for-testing-and-deployment\u002Findex",[231],{"title":227,"path":228,"stem":229},{"title":233,"path":234,"stem":235,"children":236},"Configuration Management in FastAPI","\u002Fcore-architecture-routing-patterns\u002Fconfiguration-management","core-architecture-routing-patterns\u002Fconfiguration-management\u002Findex",[237,238,244],{"title":233,"path":234,"stem":235},{"title":239,"path":240,"stem":241,"children":242},"Managing Environment Variables with Pydantic Settings","\u002Fcore-architecture-routing-patterns\u002Fconfiguration-management\u002Fmanaging-environment-variables-with-pydantic-settings","core-architecture-routing-patterns\u002Fconfiguration-management\u002Fmanaging-environment-variables-with-pydantic-settings\u002Findex",[243],{"title":239,"path":240,"stem":241},{"title":245,"path":246,"stem":247,"children":248},"Pydantic Settings vs Dynaconf vs python-decouple","\u002Fcore-architecture-routing-patterns\u002Fconfiguration-management\u002Fpydantic-settings-vs-dynaconf-vs-python-decouple","core-architecture-routing-patterns\u002Fconfiguration-management\u002Fpydantic-settings-vs-dynaconf-vs-python-decouple\u002Findex",[249],{"title":245,"path":246,"stem":247},{"title":251,"path":252,"stem":253,"children":254},"Dependency Injection Strategies in FastAPI","\u002Fcore-architecture-routing-patterns\u002Fdependency-injection-strategies","core-architecture-routing-patterns\u002Fdependency-injection-strategies\u002Findex",[255,256,262],{"title":251,"path":252,"stem":253},{"title":257,"path":258,"stem":259,"children":260},"Best Practices for FastAPI Dependency Injection","\u002Fcore-architecture-routing-patterns\u002Fdependency-injection-strategies\u002Fbest-practices-for-fastapi-dependency-injection","core-architecture-routing-patterns\u002Fdependency-injection-strategies\u002Fbest-practices-for-fastapi-dependency-injection\u002Findex",[261],{"title":257,"path":258,"stem":259},{"title":263,"path":264,"stem":265,"children":266},"Fixing FastAPI Dependency Injection Circular Imports","\u002Fcore-architecture-routing-patterns\u002Fdependency-injection-strategies\u002Ffastapi-dependency-injection-circular-import-fix","core-architecture-routing-patterns\u002Fdependency-injection-strategies\u002Ffastapi-dependency-injection-circular-import-fix\u002Findex",[267],{"title":263,"path":264,"stem":265},{"title":269,"path":270,"stem":271,"children":272},"Error Handling and Global Exceptions in FastAPI","\u002Fcore-architecture-routing-patterns\u002Ferror-handling-global-exceptions","core-architecture-routing-patterns\u002Ferror-handling-global-exceptions\u002Findex",[273,274],{"title":269,"path":270,"stem":271},{"title":275,"path":276,"stem":277,"children":278},"Global Exception Handlers for Consistent API Responses","\u002Fcore-architecture-routing-patterns\u002Ferror-handling-global-exceptions\u002Fglobal-exception-handlers-for-consistent-api-responses","core-architecture-routing-patterns\u002Ferror-handling-global-exceptions\u002Fglobal-exception-handlers-for-consistent-api-responses\u002Findex",[279],{"title":275,"path":276,"stem":277},{"title":281,"path":282,"stem":283,"children":284},"Middleware Implementation in FastAPI","\u002Fcore-architecture-routing-patterns\u002Fmiddleware-implementation","core-architecture-routing-patterns\u002Fmiddleware-implementation\u002Findex",[285,286],{"title":281,"path":282,"stem":283},{"title":287,"path":288,"stem":289,"children":290},"Implementing Custom Middleware for Request Tracing","\u002Fcore-architecture-routing-patterns\u002Fmiddleware-implementation\u002Fimplementing-custom-middleware-for-request-tracing","core-architecture-routing-patterns\u002Fmiddleware-implementation\u002Fimplementing-custom-middleware-for-request-tracing\u002Findex",[291],{"title":287,"path":288,"stem":289},{"title":293,"path":294,"stem":295,"children":296},"Modular Router Organization in FastAPI","\u002Fcore-architecture-routing-patterns\u002Fmodular-router-organization","core-architecture-routing-patterns\u002Fmodular-router-organization\u002Findex",[297,298,304],{"title":293,"path":294,"stem":295},{"title":299,"path":300,"stem":301,"children":302},"APIRouter Prefix vs Sub-Application Mounting in FastAPI","\u002Fcore-architecture-routing-patterns\u002Fmodular-router-organization\u002Fapirouter-prefix-vs-sub-application-mounting","core-architecture-routing-patterns\u002Fmodular-router-organization\u002Fapirouter-prefix-vs-sub-application-mounting\u002Findex",[303],{"title":299,"path":300,"stem":301},{"title":305,"path":306,"stem":307,"children":308},"How to Structure Large FastAPI Projects for Scale","\u002Fcore-architecture-routing-patterns\u002Fmodular-router-organization\u002Fhow-to-structure-large-fastapi-projects-for-scale","core-architecture-routing-patterns\u002Fmodular-router-organization\u002Fhow-to-structure-large-fastapi-projects-for-scale\u002Findex",[309],{"title":305,"path":306,"stem":307},{"id":311,"title":299,"body":312,"description":817,"extension":818,"meta":819,"navigation":510,"path":300,"seo":863,"stem":301,"__hash__":864},"content\u002Fcore-architecture-routing-patterns\u002Fmodular-router-organization\u002Fapirouter-prefix-vs-sub-application-mounting\u002Findex.md",{"type":313,"value":314,"toc":806},"minimark",[315,319,326,355,364,369,378,382,468,472,477,582,586,678,682,714,718,775,779,802],[316,317,299],"h1",{"id":318},"apirouter-prefix-vs-sub-application-mounting-in-fastapi",[320,321,322],"p",{},[323,324,325],"strong",{},"Key takeaways:",[327,328,329,337,343,349,352],"ul",{},[330,331,332,336],"li",{},[333,334,335],"code",{},"include_router"," composes into one app: shared schema, middleware, and handlers.",[330,338,339,342],{},[333,340,341],{},"mount"," attaches an independent app: its own schema, middleware, and lifespan.",[330,344,345,346,348],{},"Default to ",[333,347,335],{}," for a cohesive API.",[330,350,351],{},"Mount only when a section needs genuine isolation.",[330,353,354],{},"A mounted app inherits nothing, so re-add cross-cutting concerns to it.",[320,356,357,358,363],{},"This decision guide supports ",[359,360,362],"a",{"href":361},"\u002Fcore-architecture-routing-patterns\u002Fmodular-router-organization\u002F","Modular Router Organization",".",[365,366,368],"h2",{"id":367},"the-problem-this-solves","The Problem This Solves",[320,370,371,372,374,375,377],{},"Both ",[333,373,335],{}," and ",[333,376,341],{}," put routes under a path prefix, so they look interchangeable, but they differ on everything that matters operationally: documentation, middleware, and lifecycle. Choosing wrong means either a fractured schema or a section that cannot be isolated when it needs to be.",[365,379,381],{"id":380},"the-comparison","The Comparison",[383,384,385,400],"table",{},[386,387,388],"thead",{},[389,390,391,395,397],"tr",{},[392,393,394],"th",{},"Aspect",[392,396,335],{},[392,398,399],{},"mount (sub-application)",[401,402,403,415,426,436,446,457],"tbody",{},[389,404,405,409,412],{},[406,407,408],"td",{},"OpenAPI schema",[406,410,411],{},"Shared, one document",[406,413,414],{},"Separate per app",[389,416,417,420,423],{},[406,418,419],{},"Middleware",[406,421,422],{},"Inherited from parent",[406,424,425],{},"Independent",[389,427,428,431,434],{},[406,429,430],{},"Exception handlers",[406,432,433],{},"Inherited",[406,435,425],{},[389,437,438,441,444],{},[406,439,440],{},"Lifespan",[406,442,443],{},"Shared",[406,445,425],{},[389,447,448,451,454],{},[406,449,450],{},"Prefix behavior",[406,452,453],{},"Composes",[406,455,456],{},"Mounts at a path",[389,458,459,462,465],{},[406,460,461],{},"Best for",[406,463,464],{},"One cohesive API",[406,466,467],{},"Isolated or foreign sections",[365,469,471],{"id":470},"step-by-step-choosing","Step-by-Step: Choosing",[473,474,476],"h3",{"id":475},"_1-cohesive-api-include_router","1. Cohesive API → include_router",[478,479,484],"pre",{"className":480,"code":481,"language":482,"meta":483,"style":483},"language-python shiki shiki-themes github-light","from fastapi import FastAPI\n\nfrom app.routers import v1   # Composed domain routers under \u002Fv1.\n\n\ndef create_app() -> FastAPI:\n    app = FastAPI()\n    app.include_router(v1)    # Shares schema, middleware, handlers.\n    return app\n","python","",[333,485,486,505,512,529,534,539,552,564,573],{"__ignoreMap":483},[487,488,491,495,499,502],"span",{"class":489,"line":490},"line",1,[487,492,494],{"class":493},"sD7c4","from",[487,496,498],{"class":497},"sgsFI"," fastapi ",[487,500,501],{"class":493},"import",[487,503,504],{"class":497}," FastAPI\n",[487,506,508],{"class":489,"line":507},2,[487,509,511],{"emptyLinePlaceholder":510},true,"\n",[487,513,515,517,520,522,525],{"class":489,"line":514},3,[487,516,494],{"class":493},[487,518,519],{"class":497}," app.routers ",[487,521,501],{"class":493},[487,523,524],{"class":497}," v1   ",[487,526,528],{"class":527},"sAwPA","# Composed domain routers under \u002Fv1.\n",[487,530,532],{"class":489,"line":531},4,[487,533,511],{"emptyLinePlaceholder":510},[487,535,537],{"class":489,"line":536},5,[487,538,511],{"emptyLinePlaceholder":510},[487,540,542,545,549],{"class":489,"line":541},6,[487,543,544],{"class":493},"def",[487,546,548],{"class":547},"s7eDp"," create_app",[487,550,551],{"class":497},"() -> FastAPI:\n",[487,553,555,558,561],{"class":489,"line":554},7,[487,556,557],{"class":497},"    app ",[487,559,560],{"class":493},"=",[487,562,563],{"class":497}," FastAPI()\n",[487,565,567,570],{"class":489,"line":566},8,[487,568,569],{"class":497},"    app.include_router(v1)    ",[487,571,572],{"class":527},"# Shares schema, middleware, handlers.\n",[487,574,576,579],{"class":489,"line":575},9,[487,577,578],{"class":493},"    return",[487,580,581],{"class":497}," app\n",[473,583,585],{"id":584},"_2-isolated-section-mount","2. Isolated section → mount",[478,587,589],{"className":480,"code":588,"language":482,"meta":483,"style":483},"from fastapi import FastAPI\n\n# A separate app with its own middleware and docs.\ninternal = FastAPI(title=\"Internal Admin\")\n\n\ndef create_app() -> FastAPI:\n    app = FastAPI()\n    app.mount(\"\u002Finternal\", internal)   # Independent schema and lifecycle.\n    return app\n",[333,590,591,601,605,610,633,637,641,649,657,671],{"__ignoreMap":483},[487,592,593,595,597,599],{"class":489,"line":490},[487,594,494],{"class":493},[487,596,498],{"class":497},[487,598,501],{"class":493},[487,600,504],{"class":497},[487,602,603],{"class":489,"line":507},[487,604,511],{"emptyLinePlaceholder":510},[487,606,607],{"class":489,"line":514},[487,608,609],{"class":527},"# A separate app with its own middleware and docs.\n",[487,611,612,615,617,620,624,626,630],{"class":489,"line":531},[487,613,614],{"class":497},"internal ",[487,616,560],{"class":493},[487,618,619],{"class":497}," FastAPI(",[487,621,623],{"class":622},"sqxcx","title",[487,625,560],{"class":493},[487,627,629],{"class":628},"sYBdl","\"Internal Admin\"",[487,631,632],{"class":497},")\n",[487,634,635],{"class":489,"line":536},[487,636,511],{"emptyLinePlaceholder":510},[487,638,639],{"class":489,"line":541},[487,640,511],{"emptyLinePlaceholder":510},[487,642,643,645,647],{"class":489,"line":554},[487,644,544],{"class":493},[487,646,548],{"class":547},[487,648,551],{"class":497},[487,650,651,653,655],{"class":489,"line":566},[487,652,557],{"class":497},[487,654,560],{"class":493},[487,656,563],{"class":497},[487,658,659,662,665,668],{"class":489,"line":575},[487,660,661],{"class":497},"    app.mount(",[487,663,664],{"class":628},"\"\u002Finternal\"",[487,666,667],{"class":497},", internal)   ",[487,669,670],{"class":527},"# Independent schema and lifecycle.\n",[487,672,674,676],{"class":489,"line":673},10,[487,675,578],{"class":493},[487,677,581],{"class":497},[365,679,681],{"id":680},"edge-cases-and-gotchas","Edge Cases and Gotchas",[327,683,684,698,708],{},[330,685,686,689,690,374,694,363],{},[323,687,688],{},"Lost middleware."," A mounted app does not get the parent's tracing or error envelope; configure them on it, per ",[359,691,693],{"href":692},"\u002Fcore-architecture-routing-patterns\u002Fmiddleware-implementation\u002F","Middleware Implementation",[359,695,697],{"href":696},"\u002Fcore-architecture-routing-patterns\u002Ferror-handling-global-exceptions\u002F","Error Handling and Global Exceptions",[330,699,700,703,704,707],{},[323,701,702],{},"Duplicate docs."," Mounting creates a second ",[333,705,706],{},"\u002Fdocs","; communicate which is canonical.",[330,709,710,713],{},[323,711,712],{},"Lifespan scope."," A mounted app's startup runs independently; do not assume shared resources.",[365,715,717],{"id":716},"verification","Verification",[478,719,721],{"className":480,"code":720,"language":482,"meta":483,"style":483},"def test_routing_and_isolation(client):\n    assert client.get(\"\u002Fv1\u002Fusers\u002F1\").status_code == 200      # Included router.\n    assert client.get(\"\u002Finternal\u002Fopenapi.json\").status_code == 200  # Own schema.\n",[333,722,723,733,757],{"__ignoreMap":483},[487,724,725,727,730],{"class":489,"line":490},[487,726,544],{"class":493},[487,728,729],{"class":547}," test_routing_and_isolation",[487,731,732],{"class":497},"(client):\n",[487,734,735,738,741,744,747,750,754],{"class":489,"line":507},[487,736,737],{"class":493},"    assert",[487,739,740],{"class":497}," client.get(",[487,742,743],{"class":628},"\"\u002Fv1\u002Fusers\u002F1\"",[487,745,746],{"class":497},").status_code ",[487,748,749],{"class":493},"==",[487,751,753],{"class":752},"sYu0t"," 200",[487,755,756],{"class":527},"      # Included router.\n",[487,758,759,761,763,766,768,770,772],{"class":489,"line":514},[487,760,737],{"class":493},[487,762,740],{"class":497},[487,764,765],{"class":628},"\"\u002Finternal\u002Fopenapi.json\"",[487,767,746],{"class":497},[487,769,749],{"class":493},[487,771,753],{"class":752},[487,773,774],{"class":527},"  # Own schema.\n",[365,776,778],{"id":777},"related-reading","Related Reading",[327,780,781,789],{},[330,782,783,786,787,363],{},[323,784,785],{},"Up to the topic:"," ",[359,788,362],{"href":361},[330,790,791,786,794,374,798,363],{},[323,792,793],{},"Related guides:",[359,795,797],{"href":796},"\u002Fcore-architecture-routing-patterns\u002Fmodular-router-organization\u002Fhow-to-structure-large-fastapi-projects-for-scale\u002F","Structuring Large FastAPI Projects for Scale",[359,799,801],{"href":800},"\u002Fcore-architecture-routing-patterns\u002Fapplication-factory-patterns\u002F","Application Factory Patterns",[803,804,805],"style",{},"html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sqxcx, html code.shiki .sqxcx{--shiki-default:#E36209}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}",{"title":483,"searchDepth":507,"depth":507,"links":807},[808,809,810,814,815,816],{"id":367,"depth":507,"text":368},{"id":380,"depth":507,"text":381},{"id":470,"depth":507,"text":471,"children":811},[812,813],{"id":475,"depth":514,"text":476},{"id":584,"depth":514,"text":585},{"id":680,"depth":507,"text":681},{"id":716,"depth":507,"text":717},{"id":777,"depth":507,"text":778},"When to use APIRouter with include_router versus mounting a sub-application in FastAPI: shared vs isolated docs, middleware, and lifespan, with a clear decision guide.","md",{"slug":820,"type":821,"breadcrumb":822,"datePublished":833,"dateModified":834,"howto":835,"faq":853},"apirouter-prefix-vs-sub-application-mounting","long_tail",[823,826,829,830],{"label":824,"path":825},"Home","\u002F",{"label":827,"path":828},"Core Architecture & Routing Patterns","\u002Fcore-architecture-routing-patterns\u002F",{"label":362,"path":361},{"label":831,"path":832},"APIRouter Prefix vs Sub-Application Mounting","\u002Fcore-architecture-routing-patterns\u002Fmodular-router-organization\u002Fapirouter-prefix-vs-sub-application-mounting\u002F","2026-03-05","2026-06-18",{"name":836,"steps":837},"Choose between include_router and mounting a sub-application",[838,841,844,847,850],{"name":839,"text":840},"Default to include_router","For a cohesive API, compose routers with prefixes so everything shares one schema.",{"name":842,"text":843},"Identify isolation needs","Decide whether a section needs its own middleware, docs, or lifespan.",{"name":845,"text":846},"Mount for true isolation","Mount a separate FastAPI instance when a section must be independent.",{"name":848,"text":849},"Re-add cross-cutting concerns","Configure middleware and exception handlers on the sub-application too.",{"name":851,"text":852},"Verify routing and docs","Confirm paths resolve and each app exposes the intended schema.",[854,857,860],{"q":855,"a":856},"What is the difference between include_router and mount in FastAPI?","include_router composes an APIRouter into the same application, sharing its OpenAPI schema, middleware, and exception handlers, with prefixes that compose. mount attaches an entirely separate ASGI application at a path, which has its own schema, middleware, and lifespan and does not inherit the parent's. The first is for cohesion; the second is for isolation.",{"q":858,"a":859},"When should I mount a sub-application instead of including a router?","Mount when a section genuinely needs to be independent: a different middleware stack, its own OpenAPI document, an isolated lifespan, or even a different framework. Examples are an internal admin API, a webhook receiver with relaxed limits, or a legacy app served under a path. For everything within one product API, include_router is simpler.",{"q":861,"a":862},"Does a mounted sub-application inherit the parent's middleware?","No. A mounted app is independent, so it does not inherit the parent's middleware or exception handlers. If you need the same cross-cutting behavior — tracing, error envelopes — you must configure it on the sub-application as well, or accept that the mounted section behaves differently.",{"title":299,"description":817},"PnQYmo2qnc-U4sOx761F_hnead5gwSzJ5NhQWhve2N8",[866,866],null,1781809863303]