如何结合REST API和静态html页面?
您可以通过serveDirectory
在根路径上提供包含静态网站的目录。它必须是您的仆人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崩溃,它将被遮蔽。
为什么不是"/" :> Raw
?
看起来像我的浏览器缓存了一些静态页面。清理缓存后,"/" :> Raw
在/index.html
下没有回应。
api中的字符串文字将首先编码为合法的uri部分,因此"/"
将为"%2F"
,并且您的文件被映射到/%2F/index.html
等等。
你知道我怎么能处理的根源呢?
要服务于根路径的响应,你可以定义一个Get
端点没有前缀:
type API = Get '[HTML] RawHtml
它可以是除最后一行的API中的任何位置。
服务于一个本地文件为HTML响应,你必须区别于其他字节串的文件,也许在NEWTYPE包装它:
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
,并在你的控制器:
-- ...
:<|> fmap RawHtml (liftIO $ BS.readFile "your/file/path.html")
或者,如果该页面已有另一个地址,您可以将用户重定向到那里:
-- ...
:<|> throwError err301 { errHeaders = [("Location", "index.html")] }
它已经返回index.html。嗯,为什么究竟index.html?
serveDirectory
调用wai应用程序staticApp
设置defaultFileServerSettings
。在该环境中的用户将被重定向到index.htm
或index.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
}
你可以做'serveDirectory'如果你的静态页面已经在正确的结构。 – zakyggaps
@zakyggaps,已更新。 –
仆人API将按照从上到下的顺序进行匹配。你可以把它放在最后一行。 – zakyggaps