Skip to content

How to use middleware for a specific route only in a single APIRouter #4437

@ahnaf-zamil

Description

@ahnaf-zamil

First Check

  • I added a very descriptive title to this issue.
  • I used the GitHub search to find a similar issue and didn't find it.
  • I searched the FastAPI documentation, with the integrated search.
  • I already searched in Google "How to X in FastAPI" and didn't find any information.
  • I already read and followed all the tutorial in the docs and didn't find an answer.
  • I already checked if it is not related to FastAPI but to Pydantic.
  • I already checked if it is not related to FastAPI but to Swagger UI.
  • I already checked if it is not related to FastAPI but to ReDoc.

Commit to Help

  • I commit to help with one of those options 👆

Example Code

async def auth_required_middleware(request: Request, call_next: Coroutine):
    """Middleware for authenticating users on required routes"""
    token = str(
        request.cookies.get("token")
    )  # Stringyfy-ing because pyjwt might cry if it gets NoneType

    try:
        user_id = JWTService.verify_and_return_id(token)
        request.state.user_id = user_id
        response: StreamingResponse = await call_next(request)
        return response
    except:
        return JSONResponse(content={"description": "Unauthorized"}, status_code=401)

Description

FastAPI has a feature to have sub-apps. But it's not applicable in all cases, especially in my case where I have an APIRouter instance with 3 path operations/routes: login_user, create_user, get_logged_in_user. And I have an authentication middlware.

I spent a lot of time trying to find a way to only use that middleware in the get_logged_in_user operation, and not the other ones. But I found nothing regarding this. All I found online was using sub-apps, but I was trying to find a way to be able to use middlewares for a few specific routes in the same APIRouter instance.

So is there some kind of way where I can attach a middleware to a select few routes/operations in a single APIRouter instance? Because at the moment, the middleware is being triggered on all routes, including my user create and login path operations; which isn't practical.

This is how I'm adding my middleware, since it's in a separate file.

app.middleware("http")(
    auth_required_middleware
)  # Using decorators the way they were not meant to be ig

Operating System

Linux

Operating System Details

Linux Mint. Kernel version: 5.4.0-74-generic

DE: Not using one, just DWM

FastAPI Version

0.72.0

Python Version

Python 3.8.10

Additional Context

I have just taken a look at the source code, and it seems that the FastAPI middleware system is actually handled by Starlette. So
does that mean per-route/per-APIRouter middleware is something unrelated to FastAPI but related to Starlette itself?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions