When attempting to transition from using irep_node to get the list of fields for a query, to using lookahead, this error pops up:
RuntimeError: Invariant: no field for InjectedTestFragment
On v1.8.13, query:
<<~QUERY
query TestQuery {
node(id: "1") {
...InjectedTestFragment
id
}
}
QUERY
I tried returning nil like master does in lookahead.rb, but that results in no selections at all:
lookahead.selections
=> []
In irep_node, it seemed like it correctly resolved fragments, so it was straightforward to get the requested fields.
cc @swalkinshaw @dylanahsmith
Uh oh! I think master has some improvements to lookahead, see for example https://github.com/rmosolgo/graphql-ruby/pull/1933. (It was put on 1.9-dev, which has since been merged into master). Could you try again on master?
I'm hoping to cut a new 1.9-pre version today (waiting for #2054 at least), so if you'd rather wait for a Rubygems version, it shouldn't be long!
I just used master to test, and I get the same issue where .selections is an empty array for the above query
Oh! sorry to hear it. What is InjectedTestFragment in the query above? (I was guessing it was left out of the example since its contents could be assumed, is that right?)
I made a script to replicate it:
# __lookahead_test.rb
$LOAD_PATH << "./lib"
require "graphql"
puts GraphQL::VERSION
class Node < GraphQL::Schema::Object
field :id, ID, null: false
end
class Query < GraphQL::Schema::Object
field :node, Node, null: true, extras: [:lookahead] do
argument :id, ID, required: true
end
def node(id:, lookahead:)
p lookahead.selections.map(&:name)
nil
end
end
class Schema < GraphQL::Schema
query(Query)
end
p Schema.execute <<-GRAPHQL
query TestQuery {
node(id: "1") {
...InjectedTestFragment
id
}
}
fragment InjectedTestFragment on Node {
__typename
}
GRAPHQL
But when I run it on my local master, it correctly shows both fields:
~/code/graphql-ruby $ ruby __lookahead_test.rb
1.9.0.pre2
[:__typename, :id]
#<GraphQL::Query::Result @query=... @to_h={"data"=>{"node"=>nil}}>
Can you update that example to demonstrate the failure you're observing?
Sorry for the delay in getting back to you... it turns out the issue is with Interfaces. Here's the modified script:
# __lookahead_test.rb
$LOAD_PATH << "./lib"
require "graphql"
puts GraphQL::VERSION
Widget = Struct.new(:id, :name)
WIDGETS = [Widget.new("1", "foo")]
module Node
include GraphQL::Schema::Interface
field :id, ID, null: false
definition_methods do
def resolve_type(object, ctx)
WidgetType
end
end
end
class WidgetType < GraphQL::Schema::Object
implements Node
field :name, String, null: false
end
class QueryRoot < GraphQL::Schema::Object
field :widget, WidgetType, null: false
field :node, Node, null: false, extras: [:lookahead] do
argument :id, ID, required: true
end
def node(id:, lookahead:)
p lookahead.selections.map(&:name)
WIDGETS.first
end
def widget
WIDGETS.first
end
end
class Schema < GraphQL::Schema
orphan_types WidgetType
query(QueryRoot)
end
p Schema.execute <<~GRAPHQL
query {
node(id: "1") {
id
... on Widget {
name
}
}
}
GRAPHQL
When this runs, we get:
1.9.0.pre2
[:id]
#<GraphQL::Query::Result @query=... @to_h={"data"=>{"node"=>{"id"=>"1", "name"=>"foo"}}}>
So the selections on the interface itself (:id) is captured, but the selections on the nested fragment are not captured.
Ohhhh thanks for figuring that out! I'll take a look early next week and follow up here.
Feel free to give it another go on master and let me know what you think 馃嵒 !
Awesome!