Header menu logo FsHttp

Response Content Transformations

There are several ways transforming the content of the returned response to something like text or JSON:

See also: Response

http {
    POST "https://reqres.in/api/users"
    CacheControl "no-cache"
    body
    json """
    {
        "name": "morpheus",
        "job": "leader"
    }
    """
}
|> Request.send
|> Response.toJson

JSON dynamic processing:

http {
    GET @"https://reqres.in/api/users?page=2&delay=3"
}
|> Request.send
|> Response.toJson
|> fun json -> json?page.GetInt32()

JsonSerializerOptions / Using Tarmil-FSharp.SystemTextJson

FSharp.SystemTextJson enables JSON (de)serialization of F# types like tuples, DUs and others. To do so, use the JsonSerializeWith or one of the Response.toJsonWith functions and pass JsonSerializerOptions. Instead, it's also possible to globally configure the JsonSerializerOptions that will be used as default for any request where JSON (de)serialization is involved:

#r "nuget: FSharp.SystemTextJson"

// ---------------------------------
// Prepare global JSON configuration
// ---------------------------------

open System.Text.Json
open System.Text.Json.Serialization

FsHttp.GlobalConfig.Json.defaultJsonSerializerOptions <-
    let options = JsonSerializerOptions()
    options.Converters.Add(JsonFSharpConverter())
    options

// -----------------
// ... make requests
// -----------------

type Person = { name: string; age: int; address: string option }
let john = { name ="John"; age = 23; address = Some "whereever" }

http {
    POST "loopback body"
    body
    jsonSerialize john
}
|> Request.send
|> Response.deserializeJson<Person>
|> fun p -> p.address = john.address // true

Download a file

You can easily save the response content as file:

// Downloads the nupkg file as zip
get "https://www.nuget.org/api/v2/package/G-Research.FSharp.Analyzers/0.1.5" 
|> Request.send
|> Response.saveFile @"C:\Downloads\analyzers.zip"
namespace FsHttp
Multiple items
static member HttpBuilder.http: HeaderContext

--------------------
property HttpBuilder.http: HeaderContext with get
custom operation: POST (string) Calls IRequestContext.Post
custom operation: CacheControl (string) Calls IRequestContext.CacheControl
<summary> Used to specify directives that MUST be obeyed by all caching mechanisms along the request/response chain </summary>
custom operation: body Calls IRequestContext.Body
<summary> An explicit transformation from a previous context to allow for describing the request body. </summary>
custom operation: json (string) Calls IRequestContext.Json
Multiple items
module Request from FsHttp.Print

--------------------
module Request from FsHttp

--------------------
type Request = { header: Header content: BodyContent config: Config printHint: PrintHint }
val send: request: IToRequest -> Response
<summary> Sends a request synchronously. </summary>
Multiple items
module Response from FsHttp.Print

--------------------
module Response from FsHttp

--------------------
type Response = { request: Request requestMessage: HttpRequestMessage content: HttpContent headers: HttpResponseHeaders reasonPhrase: string statusCode: HttpStatusCode version: Version printHint: PrintHint originalHttpRequestMessage: HttpRequestMessage originalHttpResponseMessage: HttpResponseMessage ... } interface IDisposable interface IUpdatePrintHint<Response>
val toJson: response: Response -> System.Text.Json.JsonElement
custom operation: GET (string) Calls IRequestContext.Get
val json: System.Text.Json.JsonElement
namespace System
namespace System.Text
namespace System.Text.Json
namespace System.Text.Json.Serialization
module GlobalConfig from FsHttp
module Json from FsHttp.GlobalConfig
val mutable defaultJsonSerializerOptions: JsonSerializerOptions
val options: JsonSerializerOptions
Multiple items
type JsonSerializerOptions = new: unit -> unit + 2 overloads member AddContext<'TContext (requires default constructor and 'TContext :> JsonSerializerContext)> : unit -> unit member GetConverter: typeToConvert: Type -> JsonConverter member GetTypeInfo: ``type`` : Type -> JsonTypeInfo member MakeReadOnly: unit -> unit + 1 overload member TryGetTypeInfo: ``type`` : Type * typeInfo: byref<JsonTypeInfo> -> bool member AllowTrailingCommas: bool member Converters: IList<JsonConverter> member DefaultBufferSize: int member DefaultIgnoreCondition: JsonIgnoreCondition ...
<summary>Provides options to be used with <see cref="T:System.Text.Json.JsonSerializer" />.</summary>

--------------------
JsonSerializerOptions() : JsonSerializerOptions
JsonSerializerOptions(defaults: JsonSerializerDefaults) : JsonSerializerOptions
JsonSerializerOptions(options: JsonSerializerOptions) : JsonSerializerOptions
property JsonSerializerOptions.Converters: System.Collections.Generic.IList<JsonConverter> with get
<summary>Gets the list of user-defined converters that were registered.</summary>
<returns>The list of custom converters.</returns>
System.Collections.Generic.ICollection.Add(item: JsonConverter) : unit
Multiple items
type JsonFSharpConverter = inherit JsonConverterFactory new: fsOptions: JsonFSharpOptions * [<Optional>] overrides: IDictionary<Type,JsonFSharpOptions> -> JsonFSharpConverter + 2 overloads override CanConvert: typeToConvert: Type -> bool override CreateConverter: typeToConvert: Type * options: JsonSerializerOptions -> JsonConverter member Options: JsonFSharpOptions member Overrides: (JsonFSharpOptions -> IDictionary<Type,JsonFSharpOptions>)

--------------------
type JsonFSharpConverterAttribute = inherit JsonConverterAttribute interface IJsonFSharpConverterAttribute new: fsOptions: JsonFSharpOptions -> JsonFSharpConverterAttribute + 2 overloads override CreateConverter: typeToConvert: Type -> JsonConverter member AllowNullFields: bool with set member BaseUnionEncoding: JsonUnionEncoding with set member IncludeRecordProperties: bool with set member SkippableOptionFields: SkippableOptionFields with set member Types: JsonFSharpTypes with set member UnionAllowUnorderedTag: bool with set ...

--------------------
new: unit -> JsonFSharpConverter
new: fsOptions: JsonFSharpOptions * [<System.Runtime.InteropServices.Optional>] overrides: System.Collections.Generic.IDictionary<System.Type,JsonFSharpOptions> -> JsonFSharpConverter
new: [<System.Runtime.InteropServices.Optional; System.Runtime.InteropServices.DefaultParameterValue ((enum<JsonUnionEncoding> (19457) :> obj))>] unionEncoding: JsonUnionEncoding * [<System.Runtime.InteropServices.Optional; System.Runtime.InteropServices.DefaultParameterValue (("Case" :> obj))>] unionTagName: JsonUnionTagName * [<System.Runtime.InteropServices.Optional; System.Runtime.InteropServices.DefaultParameterValue (("Fields" :> obj))>] unionFieldsName: JsonUnionFieldsName * [<System.Runtime.InteropServices.Optional; System.Runtime.InteropServices.DefaultParameterValue ((null :> obj))>] unionTagNamingPolicy: JsonNamingPolicy * [<System.Runtime.InteropServices.Optional; System.Runtime.InteropServices.DefaultParameterValue ((null :> obj))>] unionFieldNamingPolicy: JsonNamingPolicy * [<System.Runtime.InteropServices.Optional; System.Runtime.InteropServices.DefaultParameterValue ((false :> obj))>] unionTagCaseInsensitive: bool * [<System.Runtime.InteropServices.Optional; System.Runtime.InteropServices.DefaultParameterValue ((false :> obj))>] allowNullFields: bool * [<System.Runtime.InteropServices.Optional; System.Runtime.InteropServices.DefaultParameterValue ((false :> obj))>] includeRecordProperties: bool * [<System.Runtime.InteropServices.Optional; System.Runtime.InteropServices.DefaultParameterValue ((enum<JsonFSharpTypes> (4095) :> obj))>] types: JsonFSharpTypes * [<System.Runtime.InteropServices.Optional; System.Runtime.InteropServices.DefaultParameterValue ((false :> obj))>] allowOverride: bool * [<System.Runtime.InteropServices.Optional>] overrides: System.Collections.Generic.IDictionary<System.Type,JsonFSharpOptions> -> JsonFSharpConverter

--------------------
new: unit -> JsonFSharpConverterAttribute
new: fsOptions: JsonFSharpOptions -> JsonFSharpConverterAttribute
new: [<System.Runtime.InteropServices.Optional; System.Runtime.InteropServices.DefaultParameterValue ((enum<JsonUnionEncoding> (19457) ||| enum<JsonUnionEncoding> (-2147483648) :> obj))>] unionEncoding: JsonUnionEncoding * [<System.Runtime.InteropServices.Optional; System.Runtime.InteropServices.DefaultParameterValue (("Case" :> obj))>] unionTagName: JsonUnionTagName * [<System.Runtime.InteropServices.Optional; System.Runtime.InteropServices.DefaultParameterValue (("Fields" :> obj))>] unionFieldsName: JsonUnionFieldsName * [<System.Runtime.InteropServices.Optional; System.Runtime.InteropServices.DefaultParameterValue ((enum<JsonKnownNamingPolicy> (0) :> obj))>] unionTagNamingPolicy: JsonKnownNamingPolicy * [<System.Runtime.InteropServices.Optional; System.Runtime.InteropServices.DefaultParameterValue ((enum<JsonKnownNamingPolicy> (0) :> obj))>] unionFieldNamingPolicy: JsonKnownNamingPolicy * [<System.Runtime.InteropServices.Optional; System.Runtime.InteropServices.DefaultParameterValue ((false :> obj))>] unionTagCaseInsensitive: bool * [<System.Runtime.InteropServices.Optional; System.Runtime.InteropServices.DefaultParameterValue ((false :> obj))>] allowNullFields: bool * [<System.Runtime.InteropServices.Optional; System.Runtime.InteropServices.DefaultParameterValue ((false :> obj))>] includeRecordProperties: bool * [<System.Runtime.InteropServices.Optional; System.Runtime.InteropServices.DefaultParameterValue ((enum<JsonFSharpTypes> (4095) :> obj))>] types: JsonFSharpTypes -> JsonFSharpConverterAttribute
type Person = { name: string age: int address: string option }
Multiple items
val string: value: 'T -> string

--------------------
type string = System.String
Multiple items
val int: value: 'T -> int (requires member op_Explicit)

--------------------
type int = int32

--------------------
type int<'Measure> = int
type 'T option = Option<'T>
val john: Person
union case Option.Some: Value: 'T -> Option<'T>
custom operation: jsonSerialize ('a) Calls IRequestContext.JsonSerialize
val deserializeJson: response: Response -> 'a
val p: Person
Person.address: string option
val get: url: string -> HeaderContext
val saveFile: fileName: string -> response: Response -> unit

Type something to start searching.