You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Yesod路由中接收UserId列表?解决作用域报错问题

在Yesod路由中接收UserId列表的正确姿势

这个问题我之前踩过坑!你遇到的报错是因为Yesod找不到UserIds这个类型——没错,你不需要自定义这个类型,直接用[UserId]就可以了,具体操作如下:

1. 修正路由规则

把你原来的路由:

/api/users/display/*UserIds DisplayR GET

改成:

/api/users/display/*[UserId] DisplayR GET

这里的*[UserId]告诉Yesod:这个位置要匹配多个路径片段,并把它们解析成UserId类型的列表。比如访问/api/users/display/123/456/789,就会把[UserId 123, UserId 456, UserId 789]作为参数传给DisplayR的处理函数。

2. 编写对应的Handler函数

你的Handler需要接收[UserId]类型的参数,比如:

getDisplayR :: [UserId] -> Handler Html
getDisplayR userIds = do
    -- 这里写你的业务逻辑,比如根据ID列表查询用户
    let userIdsStr = show userIds
    defaultLayout [whamlet|
        <h1>接收的用户ID列表
        <p>#{userIdsStr}
    |]

只要你的UserId类型已经实例化了PathPiece类型类(比如是newtype UserId = UserId Int,Yesod会自动为Int派生PathPiece),那么列表的解析会自动完成——Yesod会逐个解析每个路径片段为UserId,然后组合成列表。

3. 备选方案:用查询参数传递列表

如果你的ID列表很长,用路径片段可能会碰到URL长度限制,这时候可以用查询参数的方式:

  • 路由改成:
    /api/users/display DisplayR GET
    
  • Handler里通过查询参数获取列表:
    getDisplayR :: Handler Html
    getDisplayR = do
        -- 获取名为"ids"的查询参数列表
        idsStr <- lookupGetParams "ids"
        -- 把字符串转换成UserId(这里需要处理转换失败的情况)
        case traverse (parsePathPiece @UserId) idsStr of
            Left err -> sendResponseStatus status400 [shamlet|<p>无效的ID格式:#{err}|]
            Right userIds -> do
                -- 处理业务逻辑
                defaultLayout [whamlet|<p>用户ID列表:#{show userIds}|]
    
    访问的时候用/api/users/display?ids=123&ids=456&ids=789这样的URL即可。

内容的提问来源于stack exchange,提问作者Qwertie

火山引擎 最新活动