获取参数作为 key/value 元组的列表

Getting params as a list of key/value tuple

我正在实施 RESTful url,因此我可以使用 /api/v1.0/events?filter[title]="foo"&filter[content]="bar"

来过滤我的查询

是否有现有的方法将所有 filter 作为 [("title", "foo"), ("content", "bar")]

首先,我将使用 attoparsec 创建一个解析器,以获取 "filter[title]" 之类的字符串,并从中提取 return "title"

import Data.Attoparsec.Text

filterParser :: Parser Text
filterParser = do
    _ <- string "filter["
    filterKey <- takeTill (== ']')
    _ <- string "]"
    return filterKey

获取查询字符串参数,一个(Text, Text)的列表,解析成(filterKey, filterValue)对:

getHomeR :: Handler Html
getHomeR = do

    params <- reqGetParams <$> getRequest -- (1)

    let filters = catMaybes $ map (\(queryParam, filterValue) -> case maybeResult $ parse filterParser queryParam of     -- (2) (4)
                    Nothing -> Nothing          -- (3)
                    Just filterKey -> Just (filterKey, filterValue)     -- (3)
                  ) params
    liftIO $ print $ "Params are " ++ show filters
  1. 使用reqGetParams

  2. 获取查询字符串参数 来自 attoparsec 的
  3. parseParser (filterParser) 应用于查询字符串的关键部分。我们立即使用来自 attoparsec 的 maybeResult 将其变成 Maybe。如果解析成功,我们得到一个 Just "title",或者如果它失败(查询参数看起来不像 "filter=[foo]"),我们得到 Nothing.

  4. 如果参数是过滤器,return Just (filterKey, filterValue),否则Nothing.

  5. 使用 catMaybes 从列表中删除所有 Nothing,只给我们 [(filterKey, filterValue)] 对。

注意事项:

  1. 此代码不处理转义。我怀疑你是否需要支持类似 "filter[foo\]bar]" 的东西。
  2. 此代码不会删除查询参数值周围的引号。我认为你应该尽可能不要发送那些,因为你没有使用它们。
  3. 我不太擅长写解析代码。如果你愿意,你可以使用正则表达式。