Skip to content

dispatcher.py / DispatcherMiddleware review #135

Description

@dimaqq

Hi,

I've recently had to tackle transitioning from WSGI-based codebase to ASGI, and I found the dispatcher and wsgi submodules quite useful, however upon close inspection, I had to override some behaviour.

Here are a few issues that I see, let me bring these to everyone's attention and maybe start a discussion on specific items.

Design choice for path prefix

The official example:

dispatcher_app = DispatcherMiddleware({
    "/graphql": graphql_app,
    "/": static_app,
})

What it does't state is that the prefix will not be passed to the mounted app/middleware. That is, request to /graphql/foo will actually appear as /foo to graphql_app.

In my case, I have a fixed set up API endpoints, and I would prefer not to change the paths.

mounts = {
    "/v1/user": user_app,
    "/v2/pets": pets_app,
}

I would appreciate it if there was at least a flag to keep paths as they are.

Nit due to design choice for path prefix

As an experienced Pythonista, I noticed that the implementation uses .startswith() which of course accepts tuples:

mounts = {
    ("/v1", "/v2"): old_app,
    ("/v3", "/v4-bis"): new_app,
}

Which then trims the paths wrong, because len(tuple) has nothing in common with the length of the selected prefix

Lifespan broadcast

_handle_lifespan broadcasts lifespan messages to all mounted apps... But what happens if I mount the same app several times:

mounts = {
    "/v1": old_app,
    "/v2": old_app,
    "/v3": new_app
}

Lo and behold, old_app is "initialised" twice.

Prefixes are not always enough

Consider this mapping where trailing slash is mandatory

mounts = {
    "/users/": list_users,
    "/users/ada/": get_user,  # get Ada
    ...
    "/users/xena/": get_user,  # get Xena
}

Clearly, spelling out every possible prefix would be quite painful...

Likewise, consider a mapping where trailing slash is not allowed

mount = {
    "/user": list_users,
    "/user_account": list_accounts,
    "/userspace": userspace_actions,
    "/usermode": ...
}

I'm not sure if this can be solved in any other way than regexp... 🙈

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions