F # Giraffe: разные заголовки кэша в зависимости от результата - PullRequest
0 голосов
/ 14 декабря 2018

Я борюсь с тем, как установить разные заголовки ответа кеша в зависимости от того, является ли результат «ОК» или «Ошибка».Мой код выглядит примерно так (но с другими типами в результате):

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 ]

0 голосов
/ 19 декабря 2018

Я нашел решение своей проблемы.

Да, я могу связать HttpHandlers, как упоминали Джерард и Хонза Брестан, используя оператор fish (>=>).Причина, по которой я не смог выполнить эту работу, заключалась в том, что я также создал оператор fish для типа Result в открытом модуле.По сути, я создал правильный рыбный суп

Как только я реорганизовал свой код, чтобы модуль, содержащий оператор 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)
0 голосов
/ 15 декабря 2018

Обработчик кэша ответов должен передаваться в обычный конвейер.Ваш выбор между Ok и Error является функцией выбора, поэтому вы можете использовать выбор, который принимает список обработчиков, которые могут быть предприняты.Чтобы отклонить путь, просто верните task { return None }, чтобы двигаться вперед, это next ctx.

Если вы хотите сохранить всю логику в одном контроллере, как сейчас, просто сохраните соответствие и перенаправьте свой ответ json / text в один из обработчиков кэширования.

let fn = json o >=> publicResponseCaching 30 None) in fn next ctx

если он вложен в хандер, а не в конвейер, вы должны применить next & ctx

...