将params作为键/值元组的列表

时间:2016-05-22 20:48:21

标签: haskell yesod

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

过滤我的查询

是否有一种方法可以将所有filter作为[("title", "foo"), ("content", "bar")]

1 个答案:

答案 0 :(得分:1)

首先,我将使用attoparsec创建一个Parser,以获取"filter[title]"之类的字符串,并从中返回"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. parseParserfilterParser)应用于查询字符串的关键部分。我们立即使用attoparsec中的Maybe将其转换为maybeResult。如果解析成功,我们会得到Just "title",或者如果失败(查询参数看起来不像"filter=[foo]"),我们会得到Nothing

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

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

  6. 注意事项:

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