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

How do I create custom unmarshallers to process parameter lists using akka-http?

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

我正在考虑通过将多个字段与排序整数相结合来构建请求。字段和整数由 : 分隔,而字段-整数组合由逗号分隔。

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

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

这应该有效:

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 中的每个逗号分隔值。

根据 Tim 提供的答案,我得出了一个略有不同的答案。 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 =>
    ...
  }