如何在Yesod中获取含BookingId占位符的路由字符串供前端使用?
在Yesod中获取带占位符的路由模板
你可以通过以下几种方式获取带占位符的路由字符串,供前端动态替换使用:
方法一:手动构造模板字符串(简单直接)
对于已知的路由,直接在Handler中返回硬编码的模板字符串,前端后续替换占位符即可。
示例代码:
-- 定义返回路由模板的Handler getReviewDataTemplateR :: HandlerFor App Value getReviewDataTemplateR = return $ object [ "reviewDataUrlTemplate" .= ("/bookings/:bookingId/review-data" :: Text) ]
前端拿到后,只需将:bookingId替换为实际的预订ID即可生成请求URL。
优点:实现简单,无需依赖额外工具;缺点:如果后端路由定义变更,需要同步修改前端代码。
方法二:利用PathPiece实例生成占位符URL
通过给BookingId类型的PathPiece实例添加特殊逻辑,让特定值输出占位符,再用getUrlRender生成模板URL。
步骤1:修改BookingId的PathPiece实例
newtype BookingId = BookingId Int deriving (Eq, Show) instance PathPiece BookingId where -- 传入特殊值-1时,输出占位符":bookingId" toPathPiece (BookingId i) = if i == -1 then ":bookingId" else pack $ show i -- 保留原有的fromPathPiece实现 fromPathPiece s = BookingId <$> readMaybe (unpack s)
步骤2:在Handler中生成模板URL
getReviewDataTemplateR :: HandlerFor App Value getReviewDataTemplateR = do urlRender <- getUrlRender -- 传入特殊的BookingId值,生成带占位符的URL let templateUrl = urlRender $ BookingReviewDataR (BookingId (-1)) return $ object ["reviewDataUrlTemplate" .= templateUrl]
优点:路由模板与后端路由定义自动同步,无需手动维护;缺点:需要修改类型的PathPiece实例,引入特殊值逻辑。
方法三:利用Yesod内部路由元数据(通用方案)
通过Yesod内部的routePattern函数获取路由的结构定义,动态生成带占位符的模板。注意该函数属于内部模块,版本兼容性需留意。
示例代码:
import Yesod.Core import Yesod.Core.Internal.Route (RoutePattern(..), routePattern) import Data.Text (Text, intercalate) getReviewDataTemplateR :: HandlerFor App Value getReviewDataTemplateR = do -- 获取BookingReviewDataR的路由模式 let rp = routePattern (Proxy :: Proxy (Route App)) BookingReviewDataR -- 将路由模式转换为带占位符的字符串 template = case rp of RoutePattern pieces -> intercalate "/" $ map convertPiece pieces where convertPiece (Static s) = s -- 所有动态片段统一用":bookingId"作为占位符,也可根据参数名自定义 convertPiece (Dynamic _) = ":bookingId" return $ object ["reviewDataUrlTemplate" .= ("/" <> template)]
优点:通用适配任意路由,无需硬编码或修改类型实例;缺点:依赖Yesod内部API,可能随版本更新变化。
内容的提问来源于stack exchange,提问作者marcosh
相关产品推荐
相关产品推荐

