我正在努力根据结果是正常还是错误来设置不同的缓存响应标头。我的代码类似于以下内容(但结果中包含其他类型):
let resultToJson (result:Result<'a,string>) : HttpHandler =
match result with
| Ok o -> Successful.ok (json o)
| Error s -> ServerErrors.internalError (text s)
我可以通过执行以下操作来添加标题:
let resultToJson (result:Result<'a,string>) : HttpHandler =
fun (next : HttpFunc) (ctx : HttpContext) ->
let response =
let headers = ctx.Response.Headers
match result with
| Ok o ->
headers.Add("Cache-Control", new StringValues("public, max-age=10, stale-while-revalidate=2"))
headers.Add("Vary", new StringValues("Origin"))
Successful.ok (json o)
| Error s ->
headers.Add("Cache-Control", new StringValues("no-cache"))
ServerErrors.internalError (text s)
response next ctx
但这感觉不对。我想使用ResponseCaching模块中的标准HttpHandlers来设置正确的缓存头:
publicResponseCaching 10 (Some "Origin") // For Ok: Add 10 sec public cache, Vary by Origin
noResponseCaching // For Error: no caching
我该如何实现?
答案 0 :(得分:0)
应该将response cache handler用管道传输到普通管道。您可以在Ok
和Error
之间进行选择,这是一个select函数,因此您可以使用一个选择,该选择带有可以尝试的处理程序列表。要拒绝路径,只需返回task { return None }
,然后返回next ctx
。
如果您想像现在一样将所有逻辑保留在一个控制器中,只需保持匹配并将json / text响应通过管道传递到一个缓存处理程序中即可。
let fn = json o >=> publicResponseCaching 30 None) in fn next ctx
如果它嵌套在处理程序中而不是嵌套在管道中,则必须应用next
和ctx
答案 1 :(得分:0)
我找到了解决问题的方法。
是的,我可以使用fish运算符(>=>
)像Gerard和Honza Brestan所述链接HttpHandler。我之所以不能进行这项工作,是因为我还为打开的模块中的Result
类型创建了一个fish操作符。基本上我已经制作了合适的鱼汤
我重构代码以使包含Result
fish运算符的模块无法在此范围内打开时,一切工作正常。
要记住的另一点是,在终结HttpHandler之前,必须先将响应缓存称为 ,否则将不被调用:
// Simplified code
let resultToJson =
function
| Ok o -> publicResponseCaching 10 (Some "Origin") >=> Successful.ok(json o)
| Error e -> noResponseCaching >=> ServerErrors.internalError(text e)