在 Http4s 0.16.6a 中,我有以下服务。
import org.http4s.server.staticcontent._
import org.http4s._
object StaticFiles {
val basepath = ...
def apply(): HttpService = Service.lift(request => {
val file = basepath + request.uri.path
StaticFile.fromString(file, Some(request)).fold {
Pass.now // aka fallthrough
} {
NoopCacheStrategy.cache(request.pathInfo, _)
}
})
}
它从 url 获取路径并尝试确定是否可以提供静态文件。因此,一个 GET 请求/index.html
将尝试加载它,fromFile
如果找不到,则失败或“通过”。当使用 与其他服务组合时||
,这意味着总函数 (from lift
) 将被视为有点像部分函数 (from apply
)。
我似乎无法将其转换为 Http4s 0.18.x。
Http4s文档建议如下:
import cats.effect._
import org.http4s._
import org.http4s.dsl.io._
import java.io.File
val service = HttpService[IO] {
case request @ GET -> Root / "index.html" =>
StaticFile.fromFile(new File("relative/path/to/index.html"), Some(request))
.getOrElseF(NotFound()) // In case the file doesn't exist
}
这是我正在尝试做的基本形式,只是我想将它泛化一点,而不是为我想要服务的每个文件创建一个部分函数。即避免这种情况:
case request @ GET -> Root / "index.html" => ???
case request @ GET -> Root / "fileA.html" => ???
case request @ GET -> Root / "fileB.html" => ???
所以,我的问题是:
- 在 0.18 中使用时是否有
Pass
和 passthrough的概念lift
? - 如何使用
NooopCacheStretegy
withlift
? - 最终,如何将上面的代码转换为 0.18?
到目前为止,我的努力导致了这种可憎(obvs 无法编译):
def apply(): HttpService[IO] = HttpService.lift(request => {
val target = basepath + request.uri.path
StaticFile.fromString[IO](target, Some(request)).fold {
// passthrough
IO.pure(???)
} {
// process request
response => NoopCacheStrategy[IO].cache(request.pathInfo, response).unsafeRunSync()
}
})
请注意,我正在尝试使用HttpService.lift
not OptionT.liftF
(如推荐的那样)。主要是因为我不知道怎么做!