F# Giraffe: разные заголовки кэша в зависимости от результата
Я борюсь с тем, как установить различные заголовки ответа кеша в зависимости от того, является ли результат "ОК" или "Ошибка". Мой код выглядит примерно так (но с другими типами в результате):
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
Но это не правильно. Я хотел бы использовать стандартные HttpHandlers из модуля ResponseCaching для установки правильных заголовков кэша:
publicResponseCaching 10 (Some "Origin") // For Ok: Add 10 sec public cache, Vary by Origin
noResponseCaching // For Error: no caching
Как мне этого добиться?
2 ответа
Я нашел решение своей проблемы.
Да, я могу связать HttpHandlers, как упоминали Джерард и Хонза Брестан, с помощью оператора fish (>=>
). Причина, по которой я не смог сделать эту работу, была в том, что я также создал оператора по Result
введите открытый модуль. В основном я создал правильный рыбный суп
Как только я реорганизовал свой код, чтобы модуль, содержащий Result
Оператор рыбной ловли не был открыт в этой области, все работало нормально, как и ожидалось.
Еще один момент, о котором следует помнить, это то, что кеширование ответов должно вызываться до финализации HttpHandler, иначе оно не будет вызвано:
// Simplified code
let resultToJson =
function
| Ok o -> publicResponseCaching 10 (Some "Origin") >=> Successful.ok(json o)
| Error e -> noResponseCaching >=> ServerErrors.internalError(text e)
Предполагается, что обработчик кэша ответов должен быть передан в обычный конвейер. Ваш выбор между Ok
а также Error
это функция выбора, так что вы можете использовать выбор, который принимает список обработчиков, которые могут быть предприняты. Чтобы отклонить путь, просто верните task { return None }
, чтобы двигаться вперед, это next ctx
,
Если вы хотите сохранить всю логику в одном контроллере, как сейчас, просто сохраните соответствие и направьте свой ответ json/text в один из обработчиков кэширования.
let fn = json o >=> publicResponseCaching 30 None) in fn next ctx
если он вложен в Hander, а не в конвейер, вы должны применить next
& ctx