smibe
smibe

Reputation: 159

How to create nested JSON objects in FSharp

What is the best and readable solution for creating complex nexted JSON objects in F#? Something like the following JavaScript code:

{
   data: {
      user: {
        first_name:'myFirstName',
        last_name:'myLastName',
        address: {
           street: 'myStreet'
        }
      },
      type: 'user'
   }
}

Upvotes: 1

Views: 1784

Answers (4)

inwenis
inwenis

Reputation: 409

2024 update

I recommend using System.Text.Json (STJ).

open System.Text.Json.Nodes

let m = new JsonObject()
m["Name"] <- "John"
m["Address"] <- new JsonObject()
m["Address"]["Street"] <- "123 Elm St"
m["Address"]["City"] <- "Springfield"
m.ToJsonString()

Also see this post by ploeh

If you want to stick with FSharp.Data

#r "nuget: FSharp.Data"
open FSharp.Data

let d =
    JsonValue.Record [|
        "Name", JsonValue.String "John"
        "Address", JsonValue.Record [|
            "Street", JsonValue.String "123 Elm St"
            "City", JsonValue.String "Springfield"
        |]
    |]
d.ToString()

Upvotes: 0

smibe
smibe

Reputation: 159

Using JsonValue from FSharp.Data I like this one:

let data = 
    ( FSharp.Data.JsonValue.Record [|
        "event", FSharp.Data.JsonValue.String eventName; 
        "properties", FSharp.Data.JsonValue.Record 
            (Array.append [| 
                "token", FSharp.Data.JsonValue.String token;
                "distinct_id", FSharp.Data.JsonValue.String (distinctId())
            |] param)
    |])

Upvotes: 4

Scott Hutchinson
Scott Hutchinson

Reputation: 1721

To serialize any F# object or list of objects/records/unions, etc, I use this code (you might need to fill/correct some details, as I don't have the complete file available at the moment):

open System.IO

type ResultInfo = { Result: string; ErrorMsg: string } // or use built-in Result type instead

// To install the Json.NET library, enter "Install-Package Newtonsoft.Json" in the Tools...NuGet Package Manager...Package Manager Console.
// let str = Newtonsoft.Json.JsonConvert.SerializeObject(...) throws an OutOfMemoryException for large collections, so use a StreamWriter instead.
let jsonSerializeToFile obj file =
    try
        (new FileInfo(file)).Directory.Create()
        use writer = File.CreateText(file)
        let ser =  new Newtonsoft.Json.JsonSerializer()
        ser.Formatting <- Newtonsoft.Json.Formatting.Indented
        ser.Serialize(writer, obj)
        { Result = "ok"; ErrorMsg = None } // maybe return the length of the serialized string??
    with
        | ex -> { Result = "error"; ErrorMsg = Some <| ex.ToString() }

Upvotes: 0

silverfighter
silverfighter

Reputation: 6882

Chiron is a nice JSON Library https://github.com/xyncro/chiron

Json.parse """
  {
    "foo": [ { "bar": 1 }, { "bar": 2 }, { "bar": "fizz" } ],
    "test": { "one":3.5, "two":null, "three":false }
  }
"""

` results into ->

Object
  (map
     [("foo",
       Array
         [Object (map [("bar", Number 1M)]); Object (map [("bar", Number 2M)]);
          Object (map [("bar", String "fizz")])]);
      ("test",
       Object
         (map [("one", Number 3.5M); ("three", Bool false); ("two", Null null)]))])

Can also be used with types.

https://neoeinstein.github.io/blog/2015/12-15-chiron-taming-types-in-the-wild/index.html

https://neoeinstein.github.io/blog/2015/12-13-chiron-json-ducks-monads/index.html

Upvotes: 0

Related Questions