Skip to content

Double-nested router can't have empty path(despite having prefix at grandparent level) #510

@teuneboon

Description

@teuneboon

Describe the bug
If I have a router setup like this: main router -> sub router -> sub sub router. And I include sub router with a prefix, I can't have an empty path parameter on any routes in the sub sub router.

To Reproduce
Steps to reproduce the behavior:

  1. Create a file with double-nested routers:
from fastapi import APIRouter

sub_sub_router = APIRouter()
sub_router = APIRouter()
main_router = APIRouter()

main_router.include_router(sub_router, prefix='/foo')
sub_router.include_router(sub_sub_router)
  1. Add a path operation function without a path:
@sub_sub_router.get('')
def test():
    return 'bar'
  1. See error: Exception: Prefix and path cannot be both empty (path operation: test)

Expected behavior
Since at one point in the path there is a prefix, "test" should be served at /foo.

Additional context
This is probably a choice to make on whether you want to support this use-case. To explain why I do it like this: we have a pretty complex API, and to reduce complexity(and prevent files being thousands of lines long) each endpoint(i.e.: /users) has a folder structure like:

  • users/
    • __init__.py <-- contains main users router, includes read & write.py's routers
    • read.py <-- contains a router with get/read actions for users
    • write.py <-- contains a router with write actions for users
  • routes.py <-- includes the user router from users/__init__.py and sets the prefix to '/users'

So for my usecase I have 2 alternative ways to work around this issue:

  • Include read/write directly in the routes.py(this removes some abstraction though, maybe at one point we'll split it even more than just read/write)
  • Set the prefix in users/__init__.py to '/users'(this moves the route definitions to a bunch of different files which is kind of meh)

I'm perfectly fine with using one of these workarounds if I have to, but before I do I wanted to know if you see this behavior as a bug as well. I checked out pull request #415 to see if I could make a pull request that fixes this, but unfortunately I don't know how to reach the parent router in the code that was changed there.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions