Closed njlr closed 3 years ago
Hello @njlr, this is a very good question:
Perhaps there should be some way of configuring Snowflaqe to integrate the parsing in the fetch process?
Currently there isn't any way because we rely on Fable.SimpleJson
to automatically and exactly parsing the JSON into the generated types without needing any configuration. In fact, SimpleJson
understand GraphQL types and how they should be mapped (for example a GraphQL interface or union maps to a discriminated union of record type for each case).
Now SimpleJson doesn't have a way to override its way of parsing. I believe it is possible but it can be very complicated. Besides changing the automatic parsing behaviour, there needs to be also a way to tell Snowflaqe how to read use the custom converters which complicate the situation even more. Another complication is also making the fsharp
target follow these custom generators (Snowflaqe not only generates clients for Fable but also for .NET/F# consumers).
As for Thoth.Json
, it is possible to use it and instead generate F# encoders and decoders for each and every generated GraphQL type but this too has downsides:
I think the "on-the-fly" method of your code is the way to go because you can assume the data coming from the GraphQL client is always well-typed and the data always comes through as exact as it can be. If you customize the parsing, you lose this assumption.
This is more of a question and discussion rather than a bug.
Let's say I have a custom type in my model like this:
All good idiomatic F#.
Now, in my GraphQL endpoint, the product ID is encoded as GraphQL
ID
, which is just a string.So for a query like this:
GraphQL might return this:
Snowflaqe will (correctly) generate F# code that is something like this:
I want to consume this response in a Fable app, but now I have a choice to make. The generated Snowflaqe code has
product.id
as astring
, but ideally I would have aProductID
.Right now, the options I can see are:
id |> ProductID.tryParse |> Option.get
. This might fail at run-time, but only in predictable places.Query
that has everything properly parsed and do the parsing immediately after the fetch step:This give ultimate safety, but it's lots of extra code.
The
ProductID
is just an example of this problem, but there are many other cases where it appears. I am currently using the "parse on-the-fly" approach in my own code.Perhaps there should be some way of configuring Snowflaqe to integrate the parsing in the fetch process? Or maybe I am missing a simple pattern for solving this? I'm not sure what this would look like, so I thought it would be best to start a discussion here.
It might also be interesting to leverage
Thoth.Json
decoders here, since I usually already have those for other purposes.