Open MangelMaxime opened 5 years ago
Comment by MangelMaxime Friday Aug 23, 2019 at 10:15 GMT
Hello,
what's the JSON output of .Net side
when applying the encoder to [<Struct>]
?
Comment by et1975 Friday Aug 23, 2019 at 12:31 GMT
Struct types retain the shape of their non-struct types, so currently it looks like any other DU:
["AttributeId","00000000-0000-0000-0000-000000000000"]
Edit: Basically it seems an unnecessary overhead to put the single-case DU's case into the payload, but I understand it may be surprising to someone. Perhaps on .NET side Thoth could have an encoder that's not plugged in by default, or only plugged in for [<NoAlloc>]
single-case DUs (the attribute Thoth.Net would have to define)? Actually, NoAlloc
would have to be the alias like I show here, so introducing such type would only make the confusion worse - someone using Struct
would get this behavior as well, so maybe have it on for Struct
single-case DUs by default or have it as an optional encoder?
Comment by MangelMaxime Friday Aug 23, 2019 at 19:23 GMT
Ok, so I need to do more test on my side because I don't see why it's not working by default. I guess the Struct
attributes is doing something to the representation of the DUs and/or break the reflection code. I never worked with Struct
before and so we don't have tests for them.
Basically it seems an unnecessary overhead to put the single-case DU's case into the payload, but I understand it may be surprising to someone.
This is not the first time someone brought this subject about JSON representation.
It has been brought when Fable.Converter was a thing (Fable 1).
And at F# Exchange, I had a discussion about it too.
I never really looked into this issue because it just impacts the JSON representation and keeps it "constant". But yes, it's making it a bit longer than needed for single-case DUs.
The complaints come when people do "strict" domain modelling like:
type AttributeId = AttributeId of Guid
type Email = Email of string
because from what I understand they consider it an alias to string
in the case of Email for example.
I several ways to activate this simplifier solution:
[<SimpleRepresentation>]
It's just an example name, this would just be an attribute for us to detect on the DU but it would not be an alias to Struct
or Erase
. People would have to write [<SimpleRepresentation; Struct>]
is they want both behaviours.What do you think?
Probably better to have an option somewhere.
It could be productive to take note of the options provided by FSharp.SystemTextJson - supporting the same formats (maybe even with the same names) would make the ecosystem more friendly. Users would be able to switch between the two libraries, or even use different libraries in different services, without running into trivial incompatibilities.
I need to check this option, but every library makes some choices about how to represents the type on JSON, so it's hard to have a standard way. Mainly, because there are pros and cons for every design :)
That's one of the reasons why we provide Thoth.Json and Thoth.Json.Net. It guarantees that JSON encoded on the server can be decoded on the client and vice-versa.
I've just noticed this thread, having come here with the same question relating to the use of single case DUs to add strength to a domain model.
I'd like to add one more use case here also - the situation where we have a server side domain model being served over an API to both a F#/Fable based client, but also to non F# clients. It would be useful to have the option where the single case DUs are just serialized as the underlying type, so they can be trivially deserialized in the non F# world, but also be deserialized back to the strict domain types in the F# client.
Issue by et1975 Wednesday Aug 14, 2019 at 15:14 GMT Originally opened as https://github.com/MangelMaxime/Thoth/issues/158
Trying to use Thoth.Json on a model I'm sharing with Saturn backend. So I plugged in Thoth as
IJsonSerializer
and everything seems to be working, however, I'm trying to optimize the use of single-case DUs and I'm applying[<Erase>]
on the Fable side and[<Struct>]
on the .NET side but that doesn't survive the roundtrip:I guess I need to plug some "extra" encoder/decoder to tell Thoth to unwrap single-case DUs?