django-ninja icon indicating copy to clipboard operation
django-ninja copied to clipboard

Apply decorators to a subset of routes/all paths under a sub-router

Open JimNero009 opened this issue 1 year ago • 2 comments

Recently, we found the need in Django to take an iterable of Django url configs and decorate the functions within them with something (in our case, observability functions to tag logs correctly).

With NinjaAPI, you can do this perfectly well with the .urls property on the top-level API. 🚀

However, if you want to decorate certain subroutes of that main API, it doesn't seem possible to do this.

For example:

router_1 = Router()
router_2 = Router()
# Imagine the routers gets a load of paths/functions registered to it...

api.add_router("prefix_1/", router_1)
api.add_router("prefix_2/", router_2)

urlpatterns = [
  path("api/", api.urls)
] 

Given that example, say I wanted to decorate all the functions under router_1 with decorator_1 and router_2 with decorator_2. As far as I can tell, I am unable to do that. Instead, I have to decorate all the functions within those routers individually, which is obviously not ideal.

Could this be possible?

JimNero009 avatar Dec 22 '23 09:12 JimNero009

Hi @JimNero009

I guess the simpliest would be to extend Router and override it:

from ninja import Router

class RouterWithDecorator(Router):
    def __init__(self, decorator, **kwargs):
             self.decorator = decorator
             super().__init__(**kwargs)
    def add_api_operation(self, path, methods, view_func, **kwargs):
            view_func = self.decorator(view_func)
            return super().add_api_operation(path, methods, view_func, **kwargs)


def my_decorator(func):
      @wraps
      def wrapper(request, ...
      ...


router1 = RouterWithDecorator(my_decorator)


@router1.get('/foo')
def foo(request)
   ...

vitalik avatar Dec 22 '23 10:12 vitalik

Hey @vitalik, nice idea. Will play with that. If that works fine, do you think it could be a candiate for first-class functionality? Perhaps a new kwargs accepting a list of decorators to apply, for example. I guess you'd have to assume the decorators passed in behaved nicely, but feels to me more of a user concern than NinjaAPI's.

JimNero009 avatar Dec 22 '23 11:12 JimNero009