For certain reasons, we have chosen the FastAPI, in order to use it as back-end tier of our multi-module production. One of its attractive features is sub application, that helps us to separate different modules with intention of making it more modular. But we are concerned about some possible deficiencies which are missing in the official documentation. There are a considerable amount of common things -- e.g data, services, etc -- that we need to share them between main module and submodule through plugins, middle-wares and dependency-injection. The questions are: Is this feature good enough for separate modules? and so: Do sub applications inherit middle-ware, plugins and dependency injection from parent app?
thanks for sharing your experiences.
the sample code in the official docs
from fastapi import FastAPI
app = FastAPI()
@app.get("/app")
def read_main():
return {"message": "Hello World from main app"}
subapi = FastAPI()
@subapi.get("/sub")
def read_sub():
return {"message": "Hello World from sub API"}
app.mount("/subapi", subapi)
I think documentation is pretty clear about it.
Whatsoever, let's keep going from your example.
This is what we got for our subapi's routes.
This is what we got for app's routes.
That's quite interesting because our subapi did not inherited
/app
, let's keep going and make things more interesting, let us run our app with a single commandAs expected we have our app's documentation in
/docs
Also we have subapi's documentation in
/subapi/docs
, there is not interesting here.So what we should expect, when we add this?
Let's run it again, but this time let's call subapi.
What do we expect to see?
/docs
/app/docs
Yes, we are right, but things goes interesting from here.
Now we have an application like Matryoshka dolls
When we send a request to
/app/subapi/sub
(Remind we ran our app withuvicorn my_app_name:subapi
)Seems like it's working fine but let's try more.
What about
/app/subapi/app/subapi/app/subapi/app/subapi/app/subapi/app/app
Are you confused? Don't be, let me explain.
When you mount a sub-application, FastAPI takes care of the mounted app, using a mechanism from the ASGI specification called a
root_path
What
root_path
does and why the example above worked?Straight-forward
root_path
says, you can reach all the routes that you defined in yourapp.routes
from yourroot_path
, let's visualize this.Now our
root_path
is/app
Let's add subapi, and it became our
root_path
.Let's add app again, and it became our
root_path
Are you not satisfied and you are saying what if I add a middleware, what is going to happen?
Easy to answer, it will not inherit.
Let me explain this with a simple example, I am going to add a middleware for my subapi.
All the data for your application is inside of
__dict__
So we can find out the difference easily by checking the 'user_middleware' key.
All the other things you add etc will work independently because they are totally different applications underneath, so you will use mounting safely.
Conclusion