#869·starlette

在安装路由时正确处理尾随斜杠

作者: ramnes创建于 2020年3月20日更新于 2024年4月17日

这个示例的问题在于,所有路由的行为都不一样:

  • curl localhost:8000 会按预期返回
  • curl localhost:8000/ 也会按预期返回
  • curl localhost:8000/users 会返回 307
  • curl localhost:8000/users/ 也会按预期返回
  • curl localhost:8000/users/bob 也会按预期返回
  • curl localhost:8000/users/bob/ 会返回 307 所以,一个路由无论是否带有尾随斜杠都会按预期返回,另一个路由只有在带有尾随斜杠时才会返回,而另一个路由只有在不带有尾随斜杠时才会返回。 当然,主页无论是带有斜杠还是没有斜杠都会按预期返回,因为你无法发送一个没有路由的 GET 请求,所有 HTTP 客户端都会将其转换为 GET /。 在这一点上,我只是在引用 #823,讨论结束时是这样的:

这是有意的,因为一个装载点总是以 /path-to-mount/{...} 的形式出现。 好吧,我们就把这个当作事实吧,但如果我想要所有装载路由都不带有尾随斜杠的情况下返回呢?这对于 API 开发来说尤其重要,因为你希望提供一致的端点。 我开始尝试使用一个空路由,即 Route('', users, methods=['GET', 'POST']),但这根本不起作用: AssertionError: Routed paths must start with '/'。 重新考虑 #823 的答案,我尝试直接在 / 上装载,即这样做,认为这将解决我的问题:

zzterm2zz
routes = [
    Route('/', homepage),
    Mount('/', routes=[
        Route('/users', users, methods=['GET', 'POST']),
        Route('/users/{username}', user),
    ])
]

这在我的实际用例中似乎很奇怪,因为你可以直接在顶层添加路由,但在我使用的实际用例中,我使用了我导入和装载的路由。而且这效果很好…直到你添加另一个 Mount,它将永远不会被解析,因为路由在第一个装载处就停止了

内容来源: Kludex/starlette