cognitedata / oryx

.NET Cross platform and highly composable middleware for building web request handlers in F#
Apache License 2.0
202 stars 10 forks source link

Async response validation #106

Open xperiandri opened 2 years ago

xperiandri commented 2 years ago

If we need to read a content on validation like this

let validateResponse (content:HttpContent) = task {
    let! result =  content.ReadAsStringAsync()
    let! stream = content.ReadAsStreamAsync()
    stream.Seek(0L, SeekOrigin.Begin) |>ignore
    return not <| result.StartsWith("<!DOCTYPE html>")
}

then validator must be asynchronous like this

let validateAsync<'TContext, 'TSource>
    (predicate: 'TSource -> Task<bool>)
    (source: Pipeline<'TContext, 'TSource>)
    : Pipeline<'TContext, 'TSource> =
    fun next ->
        { new IAsyncNext<'TContext, 'TSource> with
            member _.OnSuccessAsync(ctx, value) =
                  task{
                      let! isValid = predicate value
                      if isValid then return! next.OnSuccessAsync(ctx, value)
                      else return! next.OnErrorAsync(ctx, SkipException "Validation failed")
                }

            member _.OnErrorAsync(ctx, exn) = next.OnErrorAsync(ctx, exn)
            member _.OnCancelAsync(ctx) = next.OnCancelAsync(ctx) }
        |> source