Search code examples
pythondependency-injectionfastapi

FastAPI - dependency for validation something


Is it considered bad practice to wake up a dependency just to validate something?

In my case, I have a dependency

AdminCurrentUserDep

  • which checks if the user is an admin and raises an error or returns an admin.

And now let's say I have a router that accepts this dependency but doesn't use it internally.

@router.post(
    "/",
    response_model=GenreOutDTO,
    status_code=status.HTTP_201_CREATED
)
async def create_genre(
    genre: GenreInDTO,
    genre_service: GenreServiceDep,
    admin_user: AdminCurrentUserDep
):
    return await genre_service.create_genre(genre=genre)

The question is: is this not a bad practice, perhaps it is better in cases where functions do not interact in any way with the entities returned from the dependency, not to use the dependency, but to explicitly call this function on the inside.


Solution

  • Its perfectly fine to not explicitly use the dependency. Typically if I'm not going to use it, but want the behavior of having it loaded, I'll put it in the decorator rather than having a named arg (its more clear if it is actually being used by the route):

    @router.post(
        "/",
        response_model=GenreOutDTO,
        status_code=status.HTTP_201_CREATED
        dependencies=[Depends(AdminCurrentUserDep)]
    )
    async def create_genre(
        genre: GenreInDTO,
        genre_service: GenreServiceDep,
    ):
        return await genre_service.create_genre(genre=genre)
    

    You can also add the dependency to the router if you want a whole range of APIs to all share the behavior:

    router = APIRouter(dependencies=[Depends(AdminCurrentUserDep)])
    
    @router.post(
        "/",
        response_model=GenreOutDTO,
        status_code=status.HTTP_201_CREATED
    )
    async def create_genre(
        genre: GenreInDTO,
        genre_service: GenreServiceDep,
    ):
        return await genre_service.create_genre(genre=genre)