Serialization__

What’s the best choice for serialization from F#?

NewtonSoft.Json (with fsharplu) or messagepack (possibly with FSharpExtensions) or other?

messagepack is presumably superior in size and speed. Looks more fiddly to use but may support changes to types better?

Presumably for reliable updates to types you should write manual deserialization so you don’t delete any deserialization code, only add new code when types are changed?

I think Fleece is by far the best one around.

1 Like

As always, It Depends™. How do you define best?

Do you want the fastest serialization? Most sustainable code base? Design-by-contract?

It’s been a few years since I last did work in that area, but back then, I wrote several (level 3) REST APIs in F#, and my go-to technology for serialization was the JSON and XML type providers.

With the type providers, you define, using examples, what the JSON or XML should actually look like on the wire, and the type provider then infers the F# records from the examples.

In my situation, it was of the utmost importance that once an external contract was established, breaking changes shouldn’t happen. Designing the contract with actual JSON and XML gave me an easily manageable way to do that, and the types just became available based on the actual JSON or XML examples. I checked the JSON and XML examples into Git so that I could keep track of changes in the contract.

I never did any performance measurements of that technology choice, since it was easily fast enough for my purposes… YMMV.

2 Likes

The json/csv/xml type providers just look wrong to me. They are doing something obviously impossible, inferring the types of strings. There is no way to tell whether [“0”,“1”] comes from floats or ints or strings. Maybe if this aspect could be switched off (so strings are assumed for all primitve types) they would work predictably instead of probabilistically.

Combination of correct, sustainable, fast, and efficient is what I want. Veering towards messagepack at the moment.

“if this aspect could be switched off (so strings are assumed for all primitve types)”

It can, just set InferTypesFromValues to false.

That said, my experience with both the JSON and XML type providers it is that if you provide a list of examples, instead of a single example, you can easily nudge the type inference engine towards the type you want. Set SampleIsList to true to supply a list of examples, instead of a single example.

In any case, there’s nothing probabilistic about the type inference engine. It’s entirely deterministic.

Whether it addresses your problem is a different story. If one starts with the external contract, like I did, then the JSON example documents represent the truth, and the inferred types will have to follow. If, on the other hand, you start with types, and don’t care about the wire representation, then perhaps one of the other options are better.

1 Like