【问题标题】:Warning message extracting query parameters from an Akka-HTTP route从 Akka-HTTP 路由中提取查询参数的警告消息
【发布时间】:2017-06-27 21:13:53
【问题描述】:

我是第一次使用 Akka-HTTP,在构建处理带有多个参数的 GET 请求的路由时遇到了一些问题。这是我的路线的简化版本——它接受 2 个查询参数,然后将它们包装在一个案例类中并以 JSON 格式返回它们(使用 Circe):

def echo(latitude: Double, longitude: Double) = Future.successful { Coordinates(latitude, longitude) }

    val route = get {
      pathPrefix("foo") {
        path("echo") {
          parameters('latitude.as[Double], 'longitude.as[Double]) { 
            (latitude, longitude) =>
              complete(echo(latitude, longitude))
        }
      }
    }
  }

虽然这按预期工作,但我在编译期间收到以下警告:

“这里没有自动适应:使用显式括号。[警告]
签名:ParameterDirectives.parameters(pdm: akka.http.scaladsl.server.directives.ParameterDirectives.ParamMagnet): pdm.Out [warn] 给定参数:scala.Symbol("latitude").as[Double], scala.Symbol("longitude").as[Double] [warn] 适配后: ParameterDirectives.parameters((scala.Symbol("纬度").as[Double], scala.Symbol("经度").as[Double]): akka.http.scaladsl.server.directives.ParameterDirectives.ParamMagnet{类型 Out = akka.http.scaladsl.server.Directive[(Double, Double)]}) [警告]
参数('latitude.as[Double],'longitude.as[Double]){(纬度, 经度) =>"

按照不同的示例,我尝试了以下路线,但尽管它编译时没有任何警告,但它总是返回 404:

  val route = get {
    pathPrefix("foo") {
      path("echo" / DoubleNumber / DoubleNumber) { 
        (latitude, longitude) =>
          complete(echo(latitude, longitude))
    }
  }
}

如果有人知道我如何通过第一条路线修复警告或让第二条路线正常工作,我将非常感谢您的帮助。此外,我正在处理的实际服务将具有 4 个 GET 方法——不同的路径和返回类型,但它们都将具有相同的 4 个参数。有没有办法在编写路线时构建它以最大限度地减少样板文件?同样,我对 Akka-HTTP 非常陌生,因此非常感谢任何建议或建议!

谢谢, 蒂姆

【问题讨论】:

    标签: scala akka akka-http


    【解决方案1】:

    1) 编译器将您的参数与自动元组包装在一起,在这种情况下,您可能有一个会引发警告的编译器标志 (scala -Ywarn-adapted-args ?)。解决方法是使元组显式化,例如

    parameters(('latitude.as[Double], 'longitude.as[Double])) {...}
    

    2) 这个看起来不错。下面的示例主要

    object Main extends App {
      val route = get {
        pathPrefix("foo") {
          path("echo" / DoubleNumber / DoubleNumber) {
            (latitude, longitude) =>
              complete(latitude + ":" + longitude)
          }
        }
      }
    
      implicit val sys = ActorSystem()
      implicit val mat = ActorMaterializer()
    
      Http().bindAndHandle(route, "0.0.0.0", 9080)
    }
    

    适用于以下请求

    http://localhost:9080/foo/echo/2.356/25.6346

    3) 对于将逻辑部分提取到可重用函数的问题,这就是 指令 的用途。假设您要提取与 lat 和 lng 参数匹配的位,您可以执行以下操作:

      def extractLatLng(prefix: String): Directive[(Double, Double)] = path(prefix / DoubleNumber / DoubleNumber)
    
      val route = get {
        pathPrefix("foo") {
          extractLatLng("echo") { (lat, lng) ⇒
            complete(lat + ":" + lng)
          }
        }
      }
    

    【讨论】:

    • 该路由有效,但它与第一​​个路由生成的 URL 不同——第一个路由包含参数名称并使用 & 号分隔它们,而第二个路由没有参数名称并且它们用斜线分隔。因此,当我使用 httpie 或 Postman 测试第一条路线时(使用 httpie:“http GET :8080/foo/echo latitude==47.5 longitude==-91.1”,使用 Postman(或只是浏览器):“localhost:8080/foo /echo?latitude=47.5&longitude=-91.1")。我只看到后一种格式的查询参数......它们都被认为是有效的吗?是首选吗?
    • 在查询参数和路径参数之间进行选择是一个不同的问题,而不是 akka-http 特定的问题。我建议您四处寻找相关指南。
    • 感谢您的帮助...谢谢!
    猜你喜欢
    • 1970-01-01
    • 2017-02-07
    • 2020-11-22
    • 1970-01-01
    • 2015-12-09
    • 1970-01-01
    • 1970-01-01
    • 2016-11-24
    • 2016-08-03
    相关资源
    最近更新 更多