Skip to content
This repository was archived by the owner on Jul 25, 2024. It is now read-only.

Commit 451c0ec

Browse files
committed
Include Input types in response to introspection query.
Why: * Previously, the response to the full introspection query did not include Input types in its types list if they were arguments to an Input type. This became clear while working on graphql_relay as Relay relies on the result of the full introspection query which wasn't including all input types. This change addresses the need by: * While reducing types we needed a pattern match for %Input{} types to reduce their arguments.
1 parent a3939cf commit 451c0ec

2 files changed

Lines changed: 82 additions & 0 deletions

File tree

lib/graphql/type/schema.ex

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ defmodule GraphQL.Schema do
77
directives: [GraphQL.Type.Directive.t]
88
}
99

10+
alias GraphQL.Type.Input
1011
alias GraphQL.Type.Interface
1112
alias GraphQL.Type.Union
1213
alias GraphQL.Type.ObjectType
@@ -81,6 +82,19 @@ defmodule GraphQL.Schema do
8182
end
8283
end
8384

85+
defp reduce_types(typemap, %Input{} = type) do
86+
if Map.has_key?(typemap, type.name) do
87+
typemap
88+
else
89+
typemap = Map.put(typemap, type.name, type)
90+
thunk_fields = CompositeType.get_fields(type)
91+
typemap = Enum.reduce(thunk_fields, typemap, fn({_,fieldtype},typemap) ->
92+
_reduce_arguments(typemap, fieldtype)
93+
|> reduce_types(fieldtype.type)
94+
end)
95+
end
96+
end
97+
8498
defp reduce_types(typemap, %{name: name} = type), do: Map.put(typemap, name, type)
8599
defp reduce_types(typemap, nil), do: typemap
86100

test/graphql/type/introspection_test.exs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ defmodule GraphQL.Type.IntrospectionTest do
44
import ExUnit.TestHelpers
55

66
alias GraphQL.Schema
7+
alias GraphQL.Type.Input
8+
alias GraphQL.Type.Int
9+
alias GraphQL.Type.NonNull
710
alias GraphQL.Type.ObjectType
811
alias GraphQL.Type.String
912

@@ -20,6 +23,71 @@ defmodule GraphQL.Type.IntrospectionTest do
2023
end
2124
end
2225

26+
test "include input types in response to introspection query" do
27+
type = %ObjectType{
28+
name: "Thing",
29+
description: "Things",
30+
fields: %{
31+
id: %{type: %Int{}},
32+
name: %{type: %String{}},
33+
},
34+
}
35+
36+
thing_input_type = %Input{
37+
name: "ThingInput",
38+
fields: %{
39+
name: %{type: %String{}},
40+
}
41+
}
42+
43+
output_type = %ObjectType{
44+
name: "SaveThingPayload",
45+
fields: %{
46+
thing: %{
47+
type: type,
48+
resolve: fn(payload, _, _) ->
49+
payload
50+
end
51+
},
52+
},
53+
}
54+
55+
input_type = %Input{
56+
name: "SaveThingInput",
57+
fields: %{
58+
id: %{type: %NonNull{ofType: %Int{}}},
59+
params: %{type: %NonNull{ofType: thing_input_type}},
60+
}
61+
}
62+
63+
schema = %Schema{
64+
query: %ObjectType{
65+
name: "QueryRoot",
66+
fields: %{onlyField: %{type: %String{}}}
67+
},
68+
mutation: %ObjectType{
69+
name: "Mutation",
70+
description: "Root object for performing data mutations",
71+
fields: %{
72+
save_thing: %{
73+
type: output_type,
74+
args: %{
75+
input: %{
76+
type: %NonNull{ofType: input_type}
77+
}
78+
},
79+
resolve: fn(data, args, info) ->
80+
data
81+
end
82+
}
83+
}
84+
}
85+
}
86+
87+
{:ok, result} = execute(schema, GraphQL.Type.Introspection.query)
88+
assert Enum.find(result.data["__schema"]["types"], fn(type) -> type["name"] == "ThingInput" end)
89+
end
90+
2391
test "exposes descriptions on types and fields" do
2492
schema = Schema.new(%{
2593
query: %ObjectType{

0 commit comments

Comments
 (0)