1

我有简单的路由映射功能,它使用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)

出于某种原因,当我尝试使用一些不是我的服务器的参数传递GETpublished请求时,我看到了showAll方法的结果。

例如,如果我发送获取请求http://{host}:{port}/?foo=somevalue

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

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

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

4

1 回答 1

2

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

为了使这个检查更严格,如果有任何参数,你可以拒绝这种情况:

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

仅当 params 映射为空时才会匹配。

于 2020-12-02T14:21:54.017 回答