简体   繁体   English

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

[英]http4s route matching for GET requests with params on root host

I have simple rout-mapping function which using http4s :我有使用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)

For some reason when I try to pass GET request with some param which is not published to my server, I see result of showAll method.出于某种原因,当我尝试使用一些未published到我的服务器的参数传递GET请求时,我看到了showAll方法的结果。

For example, if I send get request on http://{host}:{port}/?foo=somevalue例如,如果我在http://{host}:{port}/?foo=somevalue上发送 get 请求

I expect to see something like org.http4s.dsl.impl.Status.BadRequest or org.http4s.dsl.impl.Status.NotFound in Response but I see that it matches case GET -> Root actually.我希望在Response中看到类似org.http4s.dsl.impl.Status.BadRequestorg.http4s.dsl.impl.Status.NotFound的内容,但我看到它实际上匹配case GET -> Root

Why it happens and how I can avoid this matching?为什么会发生这种情况以及如何避免这种匹配?

As I got partial functions are used for such cases when we want to define function only for some specified arguments (or types) but not for all possible inputs.当我只想为某些指定的 arguments (或类型)而不是所有可能的输入定义 function 时,我得到部分函数用于这种情况。

As already mentioned in comments, case case GET -> Root => will match all requests for the root path regardless of extra parameters.正如评论中已经提到的, case case GET -> Root =>将匹配所有对根路径的请求,而不管额外的参数。

To make this check stricter you could just reject that case if there's any parameter:为了使此检查更严格,如果有任何参数,您可以拒绝这种情况:

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

it will match only if params map is empty.仅当参数 map 为空时才会匹配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM