根主机上带有参数的 GET 请求的 http4s 路由匹配

http4s route matching for GET requests with params on root host

我有简单的路由映射函数,它使用 http4s:

import cats.syntax.all._
import org.http4s._
import org.http4s.circe._

def routeMapper: PartialFunction[Request[F], F[Response[F]]] = {
  case r @ POST -> Root => create
  case r @ PUT -> Root / id => update(id)
  case GET -> Root :? Published(published) => searchByPublishedDate(published)
  case GET -> Root                   =>
    println("show all called")
    showAll
  case GET -> Root / id              => searchById(id)
  case DELETE -> Root      => deleteAll
  case DELETE -> Root / id => delete(id)
}

object Published extends QueryParamDecoderMatcher[String]("published")

// I use this rout mapper to create HttpRoutes for HttpServer
def routes: HttpRoutes[F] = HttpRoutes.of[F](routeMapper)

出于某种原因,当我尝试将 GET 请求与一些不是 published 的参数传递给我的服务器时,我看到了 showAll 方法的结果.

例如,如果我在 http://{host}:{port}/?foo=somevalue

上发送获取请求

我希望在 Response 中看到类似 org.http4s.dsl.impl.Status.BadRequestorg.http4s.dsl.impl.Status.NotFound 的内容,但我发现它实际上与 case GET -> Root 匹配。

为什么会发生这种情况以及如何避免这种匹配?

据我所知,当我们只想为某些指定的参数(或类型)而不是所有可能的输入定义函数时,部分函数用于这种情况。

正如评论中已经提到的,case case GET -> Root => 将匹配所有对根路径的请求,而不管额外的参数。

为了使此检查更严格,如果有任何参数,您可以拒绝该案例:

case request @ GET -> Root if request.params.isEmpty =>

只有params map为空才会匹配