-
-
Notifications
You must be signed in to change notification settings - Fork 548
Description
Hello
I do like to propose a small and optional feature that will enable clean dependency injection and request-scoped context in Django Ninja, without breaking any existing behaviour.
Motivation
A lot of real-world APIs need a simple way to handle state that’s specific to each request. Think about stuff like the authenticated user, trace IDs, multi-tenant info, service instances, metadata for logging, or even just a cache that sticks around for the life of the request.
Right now, dealing with this is kind of a mess. People use middleware tricks or write custom decorators, and every codebase does it differently. An official, lightweight hook system would make dependency injection way cleaner and easier to follow.
Proposed API (fully optional)
Add two optional parameters to NinjaAPI:
api = NinjaAPI(
before_endpoint=build_context,
after_endpoint=log_or_cleanup,
)
Where:
before_endpoint(request) returns a context object
after_endpoint(request, response) post-processing
The context (ctx) is automatically injected into endpoint handlers if they include a ctx parameter:
@api.get("/items")
def list_items(request, ctx):
return {"user": ctx["user"], "trace": ctx["trace_id"]}
Endpoints not using ctx remain unchanged, 100% backward compatible
Implementation process is minimal
# ninja/operation.py
def run(self, request, *args, **kwargs):
ctx = None
if self.api.before_endpoint:
ctx = self.api.before_endpoint(request)
if ctx is not None and "ctx" in self.signature.parameters:
kwargs["ctx"] = ctx
result = self.view_func(request, *args, **kwargs)
if self.api.after_endpoint:
result = self.api.after_endpoint(request, result)
return result
The Benefits are:
- Enables clean dependency injection
- Makes request-scoped context trivial
- Great for logging, tracing, metrics, multi-tenancy
- Optional and backward compatible
- Zero breaking changes
- Very small patch
- Easier large-scale project structure
Willingness to contribute
If the maintainers approve this direction, I am happy to submit a pull request with the implementation.
The patch is small (40 lines), fully backward compatible, and easy to review.