Reputation: 159
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
Reputation: 409
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
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
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
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