F# option type does not work for Node lookup resolver (even when it works for fields)
Product
Hot Chocolate
Version
14.0.0-p.79
Link to minimal reproduction
See zip below
Steps to reproduce
Repro: Repro.zip
The entire code for quick reference:
namespace HotChocolateRepro
open HotChocolate.Types.Relay
open Microsoft.AspNetCore.Builder
open Microsoft.Extensions.DependencyInjection
open Microsoft.Extensions.Hosting
[<Node>]
type MyType(id: string) =
static member GetMyType(id: string) = Some (MyType(id))
member _.Id() = id
// This Option-wrapped field is just to show that Option-wrapping actually works for fields
member _.Nullable: string option = None
type Query() =
member _.My() = MyType("1")
module Program =
[<EntryPoint>]
let main args =
let builder = WebApplication.CreateBuilder(args)
builder.Services
.AddGraphQLServer()
.AddQueryType<Query>()
.AddFSharpTypeConverters()
.AddGlobalObjectIdentification()
|> ignore
let app = builder.Build()
app.MapGraphQL() |> ignore
app.Run()
0
Here is the query to reproduce:
query {
node(id: "TXlUeXBlCmQx") {
id
... on MyType {
nullable
}
}
}
What is expected?
{
"data": {
"node": {
"id": "TXlUeXBlCmQx",
"nullable": null
}
}
}
What is actually happening?
{
"errors": [
{
"message": "Could not resolve the actual object type from `Microsoft.FSharp.Core.FSharpOption`1[[HotChocolateRepro.MyType, HotChocolateRepro, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]` for the abstract type `node`.",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"node"
]
}
],
"data": {
"node": null
}
}
Relevant log output
No response
Additional context
It works fine when the Node lookup resolver does not return an option-wrapped value:
static member GetMyType(id: string) = MyType(id)
I have tried adding a formatter or adding/prepending a middleware in various TypeInterceptor hooks, but it does not seem to work.
I'd welcome any insights as to how I can use either a TypeInterceptor or something else to accomplish this, or confirmation that this is in fact impossible and requires changes to HC internals.
This works as long as it's done before completion. But you actually do not want to solve that with a middleware as this would slow everything down that is optional. Optional in this case represents a primitive an needs to be understood by the engine.
As mentioned I also tried a formatter, but no luck.
Am I understanding you correctly that this needs changes in HC internals, and there is nothing I can do in the library right now?
I think I know what this is .... I will have a look. The issue with node resolvers is that they kind of do not exist and are just folded into the parent. This means you cannot get a formatter into the field.
@michaelstaib, any chance this can be fixed in v16? (Preferably as well as #7023 and other issues blocking the FSharp.HotChocolate v1.0 milestone.)