JSON mapper based on System.Json for F#
F# Batchfile
Latest commit 83fcb9e Mar 10, 2016 @mausch Fix link to FSharpx
Permalink
Failed to load latest commit information.
.nuget Autorestore NuGet packages Jan 9, 2014
Fleece Filter out null keys in JSON objects Sep 18, 2014
Tests Filter out null keys in JSON objects Sep 18, 2014
packages Start tests Jan 10, 2014
.gitignore Nuspec for FSharp.Data and other minor things Sep 8, 2014
Fleece.FSharpData.nuspec Bump version to 0.4.0 Sep 8, 2014
Fleece.nuspec
Fleece.sln Fix build config Sep 8, 2014
LICENSE Initial commit Jan 9, 2014
README.md Fix link to FSharpx Mar 10, 2016
build.bat Nuspec for FSharp.Data and other minor things Sep 8, 2014

README.md

Fleece

Fleece is a JSON mapper for F#. It simplifies mapping from System.Json's JsonValue onto your types, and mapping from your types onto JsonValue. It's also available for FSharp.Data's JSON types if you prefer it over System.Json. Its design is strongly influenced by Haskell's Aeson. Like Aeson, Fleece is designed around two typeclasses (in FsControl style) ToJSON and FromJSON.

Download binaries

Example

For example, given this data type:

type Person = {
    Name: string
    Age: int
    Children: Person list
}

You can map it to JSON like this:

open System.Json
open Fleece
open Fleece.Operators

type Person with
    static member ToJSON (x: Person) =
        jobj [ 
            "name" .= x.Name
            "age" .= x.Age
            "children" .= x.Children
        ]

let p = 
    { Person.Name = "John"
      Age = 44
      Children = 
      [
        { Person.Name = "Katy"
          Age = 5
          Children = [] }
        { Person.Name = "Johnny"
          Age = 7
          Children = [] }
      ] }

printfn "%s" ((toJSON p).ToString())

And you can map it from JSON like this:

type Person with
    static member FromJSON (_: Person) =
        function
        | JObject o ->
            let name = o .@ "name"
            let age = o .@ "age"
            let children = o .@ "children"
            match name, age, children with
            | Success name, Success age, Success children -> 
                Success {
                    Person.Name = name
                    Age = age
                    Children = children
                }
            | x -> Failure (sprintf "Error parsing person: %A" x)
        | x -> Failure (sprintf "Expected person, found %A" x)

let john : Person ParseResult = parseJSON """{"name": "John", "age": 44, "children": [{"name": "Katy", "age": 5, "children": []}, {"name": "Johnny", "age": 7, "children": []}]}"""        

Though it's much easier to do this in a monadic or applicative way. For example, using FSharpPlus (which is already a dependency of Fleece):

open FSharpPlus

type Person with
    static member Create name age children = { Person.Name = name; Age = age; Children = children }

    static member FromJSON (_: Person) =
        function
        | JObject o -> Person.Create <!> (o .@ "name") <*> (o .@ "age") <*> (o .@ "children")
        | x -> Failure (sprintf "Expected person, found %A" x)

Or monadically:

type Person with
    static member FromJSON (_: Person) = 
        function
        | JObject o -> 
            monad {
                let! name = o .@ "name"
                let! age = o .@ "age"
                let! children = o .@ "children"
                return {
                    Person.Name = name
                    Age = age
                    Children = children
                }
            }
        | x -> Failure (sprintf "Expected person, found %A" x)

Or you can use the Choice monad/applicative in FSharpx.Extras instead, if you prefer.

You can see more examples in the EdmundsNet project.