This small but finely tuned set of Newtonsoft.Json
Converters provide for Simple yet versionable serialization strategies without boilerplate code, ugly renderings or nasty surprises.
- The converters are employed in diverse systems across Jet, both for [de]coding Events within Event-sourced streams, and for HTTP requests/responses. As such, format changes need to be interoperable.
- As the name suggests, the focus is on handling F# types.
- Less [converters] is more - has a converter really proved itself broadly applicable ?
- this is not the final complete set of converters; Json.net is purposefully extensible and limited only by your imagination, for better or worse
- If
Newtonsoft.Json
can or should be made to do something, it should - this library is for extensions that absolutely positively can't go into Json.net itself.
See .Tests
for rendering formats.
OptionConverter
- represents F#'sOption<'t>
as a value ornull
UnionConverter
- represents F# discriminated unions as a single Json object with named fields directly within the object (Newtonsoft.Json.Converters.DiscriminatedUnionConverter
encodes the fields as an array without names, which has some pros, but also cons) 🙏 @amjddTypeSafeEnumConverter
- represents discriminated union (without any state), as a string (Newtonsoft.Json.Converters.StringEnumConverter
permits values outside the declared values) 🙏 @amjjd
See .Tests
for usage examples.
JsonPickler
- removes boilerplate from simple converters 🙏 @EirikTsarpalisJsonIsomorphism
- allows one to cleanly map a type's internal representation to something that Json.net can already cleanly handle 🙏 @EirikTsarpalis
The core library extends Newtonsoft.Json
and is intended to work based on netstandard20
.
The tests add a reliance on FSCheck.xUnit
, xUnit.net
, and Unquote
.
Naturally, the library naturally also has a hard dependency on the FSharp.Core
standard library (Json.net's Newtonsoft.Json.Converters.DiscriminatedUnionConverter
has a softer dependency via reflection; going that extra mile here is unwarranted for now given the implementation is in F#).
In general, the intention is to keep this set of converters minimal and interoperable, e.g., many candidates are deliberately being excluded from this set; its definitely a non-goal for this to become a compendium of every possible converter. So, especially in this repo, the bar for adding converters will be exceedingly high and hence any contribution should definitely be preceded by a discussion.
Please raise GitHub issues for any questions so others can benefit from the discussion.