Skip to content

Commit 7e51ea7

Browse files
committed
Make __type introspection field nullable per spec
* Updated `TypeMetaFieldDef` to return nullable `__Type` (StructNullable). * Changed resolver to use `Seq.vtryFind`, returning null for unknown types. * Added test to verify `__type` returns null for unknown type names.
1 parent 8ed90b2 commit 7e51ea7

2 files changed

Lines changed: 16 additions & 3 deletions

File tree

src/FSharp.Data.GraphQL.Server/Planning.fs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ let TypeMetaFieldDef =
2727
Define.Field(
2828
name = "__type",
2929
description = "Request the type information of a single type.",
30-
typedef = __Type,
30+
typedef = StructNullable __Type,
3131
args = [
3232
{ Name = "name"
3333
Description = None
@@ -38,8 +38,8 @@ let TypeMetaFieldDef =
3838
],
3939
resolve = fun ctx (_:obj) ->
4040
ctx.Schema.Introspected.Types
41-
|> Seq.find (fun t -> t.Name = ctx.Arg("name"))
42-
|> IntrospectionTypeRef.Named)
41+
|> Seq.vtryFind (fun t -> t.Name = ctx.Arg("name"))
42+
|> ValueOption.map IntrospectionTypeRef.Named)
4343

4444
/// Field definition allowing to resolve a name of the current Object type at runtime.
4545
let TypeNameMetaFieldDef : FieldDef<obj> =

tests/FSharp.Data.GraphQL.Tests/IntrospectionTests.fs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,19 @@ let ``Core type definitions are considered nullable`` () =
328328
empty errors
329329
data |> equals (upcast expected)
330330

331+
[<Fact>]
332+
let ``__type must return null for unknown type name`` () =
333+
// Spec: `__type(name: String!): __Type` (nullable), so unknown type names must resolve to null.
334+
// https://spec.graphql.org/draft/#sec-Schema-Introspection.Schema
335+
let root = Define.Object("Query", [ Define.Field("onlyField", StringType) ])
336+
let schema = Schema(root)
337+
let query = """{ __type(name: "DefinitelyMissingType") { name kind } }"""
338+
let result = sync <| Executor(schema).AsyncExecute(query, getMockInputContext)
339+
let expected = NameValueLookup.ofList [ "__type", null ]
340+
ensureDirect result <| fun data errors ->
341+
empty errors
342+
data |> equals (upcast expected)
343+
331344
type User = { FirstName: string; LastName: string }
332345
type UserInput = { Name: string }
333346

0 commit comments

Comments
 (0)