Due to certain limitations, we are required to serve our Angular application from within the FastAPI backend.
The Angular app features inner routing and makes API calls to the FastAPI backend.
Our objective is to serve the dist
folder when the requested URL does not include the api
prefix, and to serve all the API endpoints when the 'api' prefix is present in the URL.
The only way that worked for us to make it work is doing the follow:
main.py
templates_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../frontend/dist'))
templates = Jinja2Templates(directory=templates_dir)
@app.get("/api")
def check_status():
return {"status": "alive"}
app.include_router(
router_a,
prefix="/api/a"
)
app.include_router(
router_b,
prefix="/api/b"
)
@app.get("/frontend/route_a")
async def serve_a(request: Request):
return templates.TemplateResponse("index.html", {"request": request})
@app.get("/frontend/route_a")
async def serve_a(request: Request):
return templates.TemplateResponse("index.html", {"request": request})
As you can see in the example each internal route of the frontend must be defined in the main.py
file.
Does anyone maybe have some experience to make it work without declaring all the routs in the main.py
file?
Any help would be appreciated.
Update
After viewing the the answers from Chris comments it's still unclear for me what i should i do.
I ended up with using this approach
@app.middleware("http")
async def redirect_to_index(request: Request, call_next):
if not request.url.path.startswith("/api/"):
response = await call_next(request)
if response.status_code == 404:
return HTMLResponse(content=open(f"{templates_dir}/index.html", "r").read(), status_code=200)
return response
else:
return await call_next(request)
Although I'm not sure if this is the optimal approach, it seems to be working for me. If anyone has suggestions for a better approach, it would be appreciated.
I haven't been able to find any guides online that explain how to make this work with FastAPI