如何创建将在 Servant 中的任何路径上触发的路由?
How to create route that will trigger on any path in Servant?
我在 Haskell Servant App 中有一个类型级函数(又名类型族),它接受一个符号并生成一个类型(路由),即
type family AppRoute (x :: Symbol) where
AppRoute x = x :> Get '[HTML] RawHtml
预计将在API中使用:
type ServerAPI =
Get '[HTML] RawHtml
:<|> UserAPI
:<|> AdminAPI
:<|> AppRoute "about"
:<|> AppRoute "contact"
:<|> AppRoute "services"
:<|> AppRoute "blog"
:<|> AppRoute "products"
对应的服务器函数为
server :: Server ServerAPI
server =
html
:<|> userServer
:<|> adminServer
:<|> html
:<|> html
:<|> html
:<|> html
:<|> html
基本上所有的 AppRoutes 都去同一个端点(原始 html 文件)。有没有办法通过写类似的东西来消除重复(指的是最后五个路线)(这不会编译)
type family AppRoute where
AppRoute = String :> Get '[HTML] RawHtml
type ServerAPI =
Get '[HTML] RawHtml
:<|> UserAPI
:<|> AdminAPI
:<|> AppRoute _ -- * the problem is here. One function is needed here
有对应的服务器
server :: Server ServerAPI
server =
html
:<|> userServer
:<|> adminServer
:<|> html
所以实际上,AppRoutes 是一个类型级别的函数,它接受任何字符串和 returns 一个路由。
综上所述,不写
:<|> AppRoute "about" :<|> AppRoute "contact" :<|> AppRoute "services" :<|> AppRoute "products"
我希望能够只写
:<|> AppRoute _
您可以使用Capture
来捕获任何路径。但是,它需要以 :
字符开头。例如
type AppRoute = Capture "routePath" String :> Get '[HTML] RawHtml
type ServerAPI =
Get '[HTML] RawHtml
:<|> UserAPI
:<|> AdminAPI
:<|> AppRoute
现在,AppRoute
将在 yourserver.com/:thisIsMyPath/
上触发并将 "thisIsMyPath"
作为端点的参数传递。我目前不知道如何绕过这个 :
。假设 html
是此时不依赖于给定路径的端点,您可以将整个服务器定义为
server :: Server ServerAPI
server = html
:<|> userServer
:<|> adminServer
:<|> const html
你可能会读到它 here。
顺便说一句,为什么不使用 type
别名而不是采用 tanky 类型的家族?在我的仆人应用程序中,我通常这样做
type AppRoute (x :: Symbol) = x :> Get '[HTML] RawHtml
效果很好。
如果有人仍在寻找答案,还有另一种方法可以捕获任何路线。看看 CaptureAll 类型
我在 Haskell Servant App 中有一个类型级函数(又名类型族),它接受一个符号并生成一个类型(路由),即
type family AppRoute (x :: Symbol) where
AppRoute x = x :> Get '[HTML] RawHtml
预计将在API中使用:
type ServerAPI =
Get '[HTML] RawHtml
:<|> UserAPI
:<|> AdminAPI
:<|> AppRoute "about"
:<|> AppRoute "contact"
:<|> AppRoute "services"
:<|> AppRoute "blog"
:<|> AppRoute "products"
对应的服务器函数为
server :: Server ServerAPI
server =
html
:<|> userServer
:<|> adminServer
:<|> html
:<|> html
:<|> html
:<|> html
:<|> html
基本上所有的 AppRoutes 都去同一个端点(原始 html 文件)。有没有办法通过写类似的东西来消除重复(指的是最后五个路线)(这不会编译)
type family AppRoute where
AppRoute = String :> Get '[HTML] RawHtml
type ServerAPI =
Get '[HTML] RawHtml
:<|> UserAPI
:<|> AdminAPI
:<|> AppRoute _ -- * the problem is here. One function is needed here
有对应的服务器
server :: Server ServerAPI
server =
html
:<|> userServer
:<|> adminServer
:<|> html
所以实际上,AppRoutes 是一个类型级别的函数,它接受任何字符串和 returns 一个路由。
综上所述,不写
:<|> AppRoute "about" :<|> AppRoute "contact" :<|> AppRoute "services" :<|> AppRoute "products"
我希望能够只写 :<|> AppRoute _
您可以使用Capture
来捕获任何路径。但是,它需要以 :
字符开头。例如
type AppRoute = Capture "routePath" String :> Get '[HTML] RawHtml
type ServerAPI =
Get '[HTML] RawHtml
:<|> UserAPI
:<|> AdminAPI
:<|> AppRoute
现在,AppRoute
将在 yourserver.com/:thisIsMyPath/
上触发并将 "thisIsMyPath"
作为端点的参数传递。我目前不知道如何绕过这个 :
。假设 html
是此时不依赖于给定路径的端点,您可以将整个服务器定义为
server :: Server ServerAPI
server = html
:<|> userServer
:<|> adminServer
:<|> const html
你可能会读到它 here。
顺便说一句,为什么不使用 type
别名而不是采用 tanky 类型的家族?在我的仆人应用程序中,我通常这样做
type AppRoute (x :: Symbol) = x :> Get '[HTML] RawHtml
效果很好。
如果有人仍在寻找答案,还有另一种方法可以捕获任何路线。看看 CaptureAll 类型