# How to Add Custom Dependencies to FastCRUD Endpoints: A Complete Guide

> Learn to add custom dependencies to FastCRUD endpoints effectively. This guide details using create_deps, read_deps, and more for seamless integration with FastAPI.

- Repository: [Benav Labs/fastcrud](https://github.com/benavlabs/fastcrud)
- Tags: how-to-guide
- Published: 2026-02-26

---

**FastCRUD injects custom dependencies into auto-generated CRUD operations via the `create_deps`, `read_deps`, `read_multi_deps`, `update_deps`, `delete_deps`, and `db_delete_deps` parameters, automatically wrapping each callable in FastAPI's `Depends` during router construction.**

FastCRUD is a Python library that auto-generates FastAPI CRUD endpoints from SQLAlchemy models. While the library handles database sessions automatically, production applications require additional layers such as authentication, authorization, or multi-tenant context. According to the benavlabs/fastcrud source code, the library exposes explicit dependency parameters for each operation type and processes them through an internal `inject_dependencies` utility that validates and wraps callables before passing them to FastAPI's router factory.

## How Dependency Injection Works in FastCRUD

FastCRUD constructs its FastAPI routers by composing dependency injection blocks supplied at router creation time. The flow follows three distinct stages:

1. **User-provided callables** are passed to `crud_router` through specific dependency parameters defined in [`fastcrud/endpoint/crud_router.py`](https://github.com/benavlabs/fastcrud/blob/main/fastcrud/endpoint/crud_router.py) at lines 29-35
2. The `EndpointCreator` class builds each route via `self.router.add_api_route()`, merging the dependencies by calling `inject_dependencies(deps)` as shown in [`fastcrud/endpoint/endpoint_creator.py`](https://github.com/benavlabs/fastcrud/blob/main/fastcrud/endpoint/endpoint_creator.py) at lines 71-78
3. The `inject_dependencies` function in [`fastcrud/fastapi_dependencies.py`](https://github.com/benavlabs/fastcrud/blob/main/fastcrud/fastapi_dependencies.py) (lines 174-188) validates that each object is callable and wraps it in `fastapi.Depends`

Because dependency objects are created **once at router construction time**, FastAPI resolves them automatically on every request without requiring boilerplate in your view functions.

## Adding Dependencies to Standard CRUD Endpoints

FastCRUD provides six explicit parameters for injecting dependencies into specific operations:

- `create_deps` – Applied to the POST/create endpoint
- `read_deps` – Applied to the GET/read single endpoint
- `read_multi_deps` – Applied to the GET/read multiple (list) endpoint
- `update_deps` – Applied to the PUT/PATCH/update endpoint
- `delete_deps` – Applied to the soft DELETE endpoint
- `db_delete_deps` – Applied to the hard DELETE endpoint

Each parameter accepts a list of callables that FastCRUD automatically wraps with `Depends`.

### Example: Requiring Authentication for All Operations

```python

# deps.py

from fastapi import Depends, HTTPException, status

def get_current_user(token: str = Depends(...)):
    if token != "secret-token":
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
    return {"id": 1, "name": "alice"}

```

```python

# router.py

from fastcrud.endpoint import crud_router
from .models import Item
from .schemas import ItemCreate, ItemUpdate, ItemRead
from .deps import get_current_user

router = crud_router(
    session=async_session,
    model=Item,
    create_schema=ItemCreate,
    update_schema=ItemUpdate,
    select_schema=ItemRead,
    create_deps=[get_current_user],
    read_deps=[get_current_user],
    read_multi_deps=[get_current_user],
    update_deps=[get_current_user],
    delete_deps=[get_current_user],
    db_delete_deps=[get_current_user],
)

```

In this configuration, every CRUD route receives `Depends(get_current_user)` automatically. The router is built once; FastAPI resolves the dependency on every request.

## Adding Dependencies to Custom Routes

For endpoints that extend beyond standard CRUD operations, FastCRUD exposes the `add_custom_route` method in `EndpointCreator`. This method accepts a `dependencies` parameter that is processed by the same `inject_dependencies` utility used for standard operations.

According to [`fastcrud/endpoint/endpoint_creator.py`](https://github.com/benavlabs/fastcrud/blob/main/fastcrud/endpoint/endpoint_creator.py) at lines 71-79, custom routes support dependency injection through the following pattern:

```python

# custom_deps.py

from fastapi import Depends, HTTPException

def verify_admin(user: dict = Depends(get_current_user)):
    if not user.get("is_admin"):
        raise HTTPException(status_code=403, detail="Admin only")
    return True

```

```python

# router.py

from fastcrud.endpoint import crud_router
from .custom_deps import verify_admin

# First, create the standard router

router = crud_router(...)

# Access the EndpointCreator instance to add custom routes

# Note: router.routes[0].endpoint.__self__ accesses the internal creator instance

router_creator = router.routes[0].endpoint.__self__

router_creator.add_custom_route(
    endpoint=special_report,
    methods=["GET"],
    path="/admin/report",
    dependencies=[verify_admin],
    tags=["admin"],
    summary="Admin-only report",
)

```

The `dependencies` list passed to `add_custom_route` undergoes the same validation and wrapping process as standard CRUD dependencies.

## Dynamic Dependencies and Multi-Tenant Sessions

Dependencies can return values that FastCRUD passes as named parameters to your endpoint functions. This enables advanced patterns such as tenant-aware database sessions.

```python

# tenant_deps.py

from fastapi import Depends, Header

def get_tenant_db(tenant_id: str = Header(...)):
    # Resolve the appropriate async session for the tenant

    return get_async_session_for_tenant(tenant_id)

# Apply only to the list endpoint

router = crud_router(
    ...,
    read_multi_deps=[get_tenant_db],
)

```

When `get_tenant_db` resolves, FastCRUD passes the returned session object as a parameter named `tenant_db` to the read-multi endpoint, alongside the standard `db` session.

## Summary

- FastCRUD accepts custom dependencies through six operation-specific parameters: `create_deps`, `read_deps`, `read_multi_deps`, `update_deps`, `delete_deps`, and `db_delete_deps`
- Dependencies are validated and wrapped in `fastapi.Depends` by the `inject_dependencies` function located in [`fastcrud/fastapi_dependencies.py`](https://github.com/benavlabs/fastcrud/blob/main/fastcrud/fastapi_dependencies.py) at lines 174-188
- Custom routes added via `EndpointCreator.add_custom_route` support dependency injection through the `dependencies` parameter, processed at lines 71-79 of [`fastcrud/endpoint/endpoint_creator.py`](https://github.com/benavlabs/fastcrud/blob/main/fastcrud/endpoint/endpoint_creator.py)
- Dependencies are resolved **once at router construction time**, ensuring zero runtime overhead for dependency validation
- Returned dependency values are injected as named parameters into endpoint functions, enabling patterns like multi-tenant database routing

## Frequently Asked Questions

### Can I use the same dependency for all CRUD operations?

Yes. Pass the same callable to all six dependency parameters (`create_deps`, `read_deps`, `read_multi_deps`, `update_deps`, `delete_deps`, `db_delete_deps`) when calling `crud_router`. FastCRUD will wrap the callable in `Depends` for each respective endpoint, ensuring consistent authentication or logging across all operations.

### How do I add dependencies only to specific endpoints?

Supply the dependency list only to the specific parameter corresponding to the desired operation. For example, pass your authentication callable only to `delete_deps` and `db_delete_deps` if only delete operations require elevated privileges. Leave other dependency parameters empty or omitted to use FastCRUD's default behavior for those endpoints.

### What happens if a dependency returns a value?

FastAPI injects the return value as a keyword argument to your endpoint function using the dependency function's name as the parameter name. If your dependency function is named `get_current_user`, the endpoint receives a parameter `current_user` containing the resolved value. This works for both standard CRUD endpoints and custom routes added via `add_custom_route`.

### Do custom dependencies conflict with FastCRUD's automatic database session injection?

No. FastCRUD manages its own database session dependencies internally while processing your custom dependencies separately. The `inject_dependencies` utility merges both sets without conflict, ensuring your custom callables receive their resolved values alongside the standard `db` session parameter that FastCRUD generates automatically.