gpt4 book ai didi

haskell - Servant 中的 Html 页面——如何结合 REST API 和静态 html 页面?

转载 作者:行者123 更新时间:2023-12-05 00:56:19 27 4
gpt4 key购买 nike

我有一个简单的 hello world Servant 应用程序。我需要向它添加一些静态或动态的 html 页面。我怎样才能做到这一点?在文档中没有提到它。注意我不想在 Haskell 代码中创建 html 布局,我希望 Haskell 显示已经创建的 html 页面。

更新:

我怎样才能结合这个:

type MyApi = "/" :> Raw

server :: Server MyApi
server = serveDirectory "static/" -- index.html, about.html

有了我已经拥有的:
  type API = 
"api" :> "items" :> Get '[JSON] [MyData] :<|>
"api" :> "items" :> Capture "id" Int :> Get '[JSON] MyData


app :: Application
app = serve api server

api :: Proxy API
api = Proxy

server :: Server API
server = getItems :<|> getItem

startApp :: IO ()
startApp = run 1234 app

更新2:

在职的:
type API = 
"api" :> "items" :> Get '[JSON] [MyData] :<|>
"api" :> "items" :> Capture "id" Int :> Get '[JSON] MyData :<|>
Raw

不工作,根本没有反应:
type API = 
"api" :> "items" :> Get '[JSON] [MyData] :<|>
"api" :> "items" :> Capture "id" Int :> Get '[JSON] MyData :<|>
"/" :> Raw

-- or

type API =
"api" :> "items" :> Get '[JSON] [MyData] :<|>
"api" :> "items" :> Capture "id" Int :> Get '[JSON] MyData :<|>
"" :> Raw

我想知道为什么?

最佳答案

how to combine REST API and static html pages?



您可以通过 serveDirectory 在根路径提供包含您的静态网站的目录。 .它必须是您的 Servant API 中的最后一个案例,否则将永远不会匹配其他案例。
type API = 
"api" :> "items" :> Get '[JSON] [MyData] :<|>
"api" :> "items" :> Capture "id" Int :> Get '[JSON] MyData :<|>
Raw

api :: Proxy API
api = Proxy

server :: Server API
server = getItems
:<|> getItem
:<|> serveDirectory "static/"

此外,如果任何静态页面名称与您的 API 崩溃,它将被隐藏。

why isn't it "/" :> Raw?



看起来我的浏览器缓存了一些静态页面。 "/" :> Raw/index.html 下没有回应清理缓存后。

api 中的字符串文字将首先被编码为合法的 uri 部分,因此 "/"将是 "%2F"并且您的文件被映射到 /%2F/index.html等等。

do you know how can I handle the root case?



要在根路径提供响应,您可以定义 Get没有前缀的端点:
type API = Get '[HTML] RawHtml

它可以位于 API 中除最后一行之外的任何位置。

要将本地文件作为 html 响应提供,您必须将该文件与其他字节串区分开来,也许将其包装在一个新类型中:
newtype RawHtml = RawHtml { unRaw :: BS.ByteString }

-- tell Servant how to render the newtype to html page, in this case simply unwrap it
instance MimeRender HTML RawHtml where
mimeRender _ = unRaw

在你的 Controller 中:
-- ...
:<|> fmap RawHtml (liftIO $ BS.readFile "your/file/path.html")

或者,如果页面已经有另一个地址,您可以将用户重定向到那里:
-- ...
:<|> throwError err301 { errHeaders = [("Location", "index.html")] }

it already returns index.html. Hm, why exactly index.html?


serveDirectory调用 wai 应用程序 staticApp带有设置 defaultFileServerSettings .在该设置中,用户将被重定向到 index.htmindex.html如果出现问题:
defaultFileServerSettings root = StaticSettings
{ ssLookupFile = fileSystemLookup (fmap Just . hashFile) root
, ssMkRedirect = defaultMkRedirect
, ssGetMimeType = return . defaultMimeLookup . fromPiece . fileName
, ssMaxAge = NoMaxAge
, ssListing = Just defaultListing
, ssIndices = map unsafeToPiece ["index.html", "index.htm"]
, ssRedirectToIndex = False
, ssUseHash = False
, ssAddTrailingSlash = False
, ss404Handler = Nothing
}

关于haskell - Servant 中的 Html 页面——如何结合 REST API 和静态 html 页面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36372860/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com