justapi — /docs

Dependency Injection (DI) lets you declare reusable components that are automatically resolved and injected into your route handlers. JustAPI's DI system mirrors FastAPI's, making migration seamless.

Basic Dependency

A dependency is any callable that returns a value:

from justapi import JustAPIApp, Depends

app = JustAPIApp()


def common_params(q: str | None = None, skip: int = 0, limit: int = 100):
    return {"q": q, "skip": skip, "limit": limit}


@app.get("/items/")
def list_items(request, params: dict = Depends(common_params)):
    return {"endpoint": "items", **params}


@app.get("/users/")
def list_users(request, params: dict = Depends(common_params)):
    return {"endpoint": "users", **params}
curl "http://127.0.0.1:8000/items/?skip=10&limit=5"
# Output: {"endpoint":"items","q":null,"skip":10,"limit":5}

Authentication Dependency

Dependencies can raise HTTPException to reject requests:

from justapi import JustAPIApp, Depends, HTTPException, Header

app = JustAPIApp()


def verify_token(authorization: str = Header(...)):
    if not authorization.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="Invalid authorization header")
    token = authorization.removeprefix("Bearer ")
    if token != "secret-token":
        raise HTTPException(status_code=401, detail="Invalid token")
    return {"user_id": 42, "role": "admin"}


@app.get("/protected")
def protected_route(request, user: dict = Depends(verify_token)):
    return {"message": "Access granted", "user": user}
curl http://127.0.0.1:8000/protected
# Output: {"detail":"Invalid authorization header"}

curl http://127.0.0.1:8000/protected \
  -H "Authorization: Bearer secret-token"
# Output: {"message":"Access granted","user":{"user_id":42,"role":"admin"}}

Database Session Dependency

def get_db(request):
    db = app.db
    try:
        yield db
    finally:
        pass  # Connection pooling handles cleanup


@app.get("/users")
def list_users(request, db=Depends(get_db)):
    return db.query("SELECT * FROM users")

Class-Based Dependencies

class Pagination:
    def __init__(self, skip: int = 0, limit: int = 100):
        self.skip = skip
        self.limit = limit


@app.get("/items/")
def list_items(request, pagination: Pagination = Depends(Pagination)):
    return {"skip": pagination.skip, "limit": pagination.limit}

Dependency Scope & Caching

By default, dependencies are called once per request and the result is cached. All route handlers and nested dependencies share the same instance:

def get_db(request):
    print("Creating DB session")  # Called once per request
    return {"connection": "db-1"}

def get_user(request, db=Depends(get_db)):
    return {"user": "alice", "db": db}

@app.get("/profile")
def profile(request, user=Depends(get_user), db=Depends(get_db)):
    return {"user": user, "db_again": db}

In this example, get_db is called once and its result is reused by get_user and profile.

Dependency with Path(), Query(), Header()

from justapi import Path, Query, Header


def pagination(
    skip: int = Query(0, description="Number of items to skip"),
    limit: int = Query(10, description="Max items per page"),
):
    return {"skip": skip, "limit": limit}


def auth(
    user_id: int = Path(..., description="User ID"),
    authorization: str = Header(..., description="Bearer token"),
):
    if authorization != "Bearer secret":
        raise HTTPException(401)
    return {"user_id": user_id}


@app.get("/users/{user_id}/items/")
def list_items(
    request,
    auth_data: dict = Depends(auth),
    pagination_data: dict = Depends(pagination),
):
    return {**auth_data, **pagination_data}

Nested Dependencies

Dependencies can depend on other dependencies:

def get_config(request):
    return {"db_url": "postgres://localhost/mydb"}


def get_db(request, config: dict = Depends(get_config)):
    return {"connection": f"Connected to {config['db_url']}"}


@app.get("/status")
def status(request, db: dict = Depends(get_db)):
    return {"db_status": db["connection"]}

How It Works Internally

  1. JustAPI inspects function signatures at registration time
  2. Parameters with Depends() are resolved before the handler runs
  3. Dependencies execute in order (innermost first)
  4. Results are cached to avoid redundant calls
  5. HTTPException raised in a dependency short-circuits the request

Next Steps

JustAPI v2.0.9 — Open Source MIT License · Built with WebTUI · GitHub

NORMAL master justapi/docs
utf-8 Top 1:1