如何创建自定义解组器以使用akka-http处理参数列表?

时间:2019-04-05 11:13:40

标签: scala unmarshalling akka-http

我正在尝试从发送到我的路线的输入中解组参数,以便该路线能够处理这些参数并在参数格式不正确的情况下发送BadRequest。我正在解析的特定参数是REST-ful应用程序中使用的orderBy请求。

我当时正在考虑通过将多个字段与一个排序整数结合在一起来构造请求。字段和整数之间用:分隔,而字段-整数组合之间用逗号分隔。

此请求的示例如下:/path?orderBy=id:-1,name:1

我想创建一个自定义的解组器,该解组器可以将此参数列表转换为List[(String, Int)]并发送到我的查询函数,该函数将对其进行分解并在查询中使用它。 Akka-http支持CsvList解组器,但这不足以实现我的实现。

2 个答案:

答案 0 :(得分:0)

这应该有效:

implicit def pairSeq(implicit unmarshaller: Unmarshaller[String, (String, Int)]) =
  Unmarshaller.strict[String, (String, Int)] { string =>
    val Array(a, b) = string.split(':')
    a -> b.toInt
  }

...

path("PATH") {
  parameter("orderBy".as(CsvSeq[(String, Int)])) { ob =>
    ...
  }
如果参数格式正确,

ob将是List[(String, Int)]

这为(String, Int)使用了一个自定义编组器,该编组器在:处分割了字符串,并将第二个值转换为IntCsvSeq使用此自定义编组器取消选择orderBy中每个逗号分隔的值。

答案 1 :(得分:0)

根据蒂姆提供的答案,我得出了略有不同的答案。 Tim的原始答案在定义内有一个不必要的隐式参数,可以删除该隐式参数,因为此实现不需要自身的编组器。这是基本的编组器。

我这样做了:

implicit val pairSeq = Unmarshaller.strict[String, (String, Int)] { string =>
    val Array(a, b) = string.split(':')
    a -> b.toInt
  }

...

import foo.pairSeq

path("PATH") {
  parameter("orderBy".as(CsvSeq[(String, Int)])) { ob =>
    ...
  }