Home > Blockchain >  Ignore trailing slashes in aiohttp routes
Ignore trailing slashes in aiohttp routes

Time:12-20

I've been looking in to aiohttp for web services and have run in to an issue with trailing slashes on URLs. If I define a function like so:

@routes.get('/global')
async def custom_dict(request: Request) -> Response:
    print(f"Fetching global dictionary...")
    return(web.json_response(request.app['custom_dict']))

It will get called by "http://localhost:8080/global", but not with "http://localhost:8080/global/". I know I can add a slash to the route, but then "/global" no longer works. I toyed with the notion of simply having two routes, but that seems redundant.

I also looked at redirects but ran across "merge_slashes" and "append_slashes" and that seems to be the ideal. I've tried several approaches in using them and none have worked so far.

@routes.get('/global/', merge_slashes=True)

won't even run and

@routes.get('/global/')
async def custom_dict(request: Request, merge_slashes=True) -> Response:

doesn't seem to do anything.

I have the sense that there's something simple I'm missing, but danged if I can find it. I've searched on Google and tried a few random combinations and so far, no success.

Is there a way to use the route decorators and make the trailing slashes irrelevant?

CodePudding user response:

I am not sure if there is a clean way to do this from reading the docs.

You could create a route regex and handle for trailing slashes or not:

@routes.get("/global{none:[\/]{0,1}}")
async def custom_dict(request: Request) -> Response:
    print(f"Fetching global dictionary...")
    return(web.json_response(request.app['custom_dict']))

This is a hack to accept trailing slashes after the path you want to define. It expects a variable that is named none and it uses the regex after : to parse it.

I am not exactly sure if this covers only the trailing slash case, so if someone can correct me that would be helpful.

Or you can also declare multiple routes for a handler:

@routes.get('/global')
@routes.get('/global/')
async def custom_dict(request: Request) -> Response:
    print(f"Fetching global dictionary...")
    return(web.json_response(request.app['custom_dict']))
  • Related