-
-
Notifications
You must be signed in to change notification settings - Fork 339
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhancement: Have OpenAPI Schema generation respect route handler ordering #3130
Comments
Btw, @ccrvlh, I was just looking into a bit on the swagger side of things and it seems they allow grouping based on tags. If this allows you to customize the order that's displayed then imo that would be better than us trying to create them in the order since I assume that would add quite a bit of complexity. NOTE: I haven't really tested it out with the tags so I'm not sure if that will allow for the structure that you'd like. |
Yeah I usually use the tags to group "modules", my challenge is within the module. I'll take a look to see if I can find something - my impression is that instead of iterating the controller's methods, the iteration is done in difference places based on I think it might related to this logic as well: litestar/litestar/controller.py Lines 203 to 210 in 3e5c179
And if that's the case than it might not add too much complexity. I'll get back to you on this so we can at least have a better idea on the trade-offs. |
Awesome! |
Ran a couple of tests and could make it work in a sort of hacky way: # litestar/controller.py:Controller
def get_route_handlers(self) -> list[BaseRouteHandler]:
"""Get a controller's route handlers and set the controller as the handlers' owner.
Returns:
A list containing a copy of the route handlers defined on the controller
"""
route_handlers: list[BaseRouteHandler] = []
controller_names = set(dir(Controller))
self_handlers = []
for name in dir(self):
if name not in controller_names and isinstance(getattr(self, name), BaseRouteHandler):
handler = getattr(self, name)
if getattr(handler, '_fn', None):
handler_line = inspect.getsourcelines(handler._fn)[1]
self_handlers.append((handler_line, handler))
sorted_list = sorted(self_handlers, key=lambda x: x[0])
for _, self_handler in sorted_list:
route_handler = deepcopy(self_handler) The benefit is that it's a very simple change, and doesn't alter the logic on what is being iterated (path vs method vs handler) and when (controller, app, plugin, etc). The downside is that is somewhat hacky, as it depends on this This + putting |
@ccrvlh does that result in the correct output in Swagger? |
Tested on a project with a couple of hundred routes, so can't tell for sure, and haven't done any proper testing (was literally just changing the installed I'm not sure whether |
@ccrvlh while I see the benefit of this feature, I'd like to wait just a bit to see if there are others who would like this as well before adding support for this. Also, ideally, I think this ordering logic should happen within the OpenAPI plugin rather in the |
Sure. I think It might be possible to work on the ordering through the |
Summary
Opening a new issue as discussed here.
From a DX perspective I personally find very helpful to have ordered routes in the
Controller
, that follow a certain logic:GET /
comes beforeGET /:id
and beforeGET /:id/nested
)GET
,POST
,GET id
,PATCH id
,DELETE id
)Example:
Currently the ordering of the route definition at the Controller is not respected by the docs, so I end up having a Swagger that looks like this:
Which I personally find very confusing since:
(1)
It doesn't seem to follow a pre-defined logic (couldn't find any pattern for that when looking at the docs)it does seem to follow the ordering of the methods as defined here as shared by @guacs here(2) It doesn't respect the logic that was defined on the controller (specifically the nesting).
Was having a quick look and it seems to be related to logic when registering the route here, and then the handler:method map on the
HTTPRoute
here.It seems that by the time it reaches the plugin the nesting is already out of order - so it might make sense to handle when registering the routes maybe?
Anyways, if this is something of interest I'd help to contribute and take a deeper look into it.
Note
While we are open for sponsoring on GitHub Sponsors and
OpenCollective, we also utilize Polar.sh to engage in pledge-based sponsorship.
Check out all issues funded or available for funding on our Polar.sh dashboard
The text was updated successfully, but these errors were encountered: