-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Help with resolvers #166
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
✋ I don't have a really good answer 😞 The almost-answer is to inspect the query AST to see if chat messages were requested: resolve -> (obj, args, ctx) {
chats = Chat.where(id: args[:ids])
if ctx.ast_node.selections.any? { |selection| selection.name == "chat_messages"}
chats = chats.includes(:chat_messages)
end
chats
} However, this doesn't work if fields aren't requested inline: query {
chat(ids: [1,2]) { ... chatFields }
}
fragment chatFields on Chat {
chat_messages
} Now, the AST is all wonky: the selections include This could probably be improved by some pre-processing or a legitimate API to expose what fields will be requested from an object. But it wouldn't work for nested selections because of Unions: you can't say whether a |
Thanks for the info @rmosolgo! Is the AST wonkiness a deficiency of the ruby implementation? I'm wondering how how to solve this in graphql-ruby but also in general. If there is a best practice here, and graphql-ruby is just lacking, I'd love to pitch in and help. |
I've tried a couple things over the last year without any luck, but I can point to some other approaches:
By the way, there's also graphql-batch for Ruby which handles some efficiency issues. But I'd love to see some improvements in this area! |
We use this gem in conjunction with Sequel, and it includes a couple of plugins that are handling these issues quite nicely for us. For eager-loading associations, the tactical_eager_loading plugin handles them pretty seamlessly as they're accessed: https://github.com/jeremyevans/sequel/blob/master/lib/sequel/plugins/tactical_eager_loading.rb For selecting specific fields, there isn't quite as clean a solution, but we do use the lazy_attributes plugin to ensure that some fields (large text columns, for example) are lazy-loaded from the DB only when accessed: https://github.com/jeremyevans/sequel/blob/master/lib/sequel/plugins/lazy_attributes.rb It's possible that extending ActiveRecord to support things like this may be an easier task than manually walking the AST. |
0.16.0 introduces ctx.irep_node.children.each do |irep_child|
irep_child.name # alias or field name
irep_child.definition # => <#GraphQL::Field ...> Field definition
irep_child.on_types # => Set<types...> Type definitions which this field will apply to
irep_child.ast_node # => <#GraphQL::Language::Nodes::Field ... >
end I haven't had a ton of time to play around with it, but this is the data structure used for query execution now, I think it will provide better support for look-ahead too! |
I tried the AST method above but the problem is the
Is there any way to disable |
Sorry to be so late on this. Here's where offset is applied, perhaps you could skip it in case the offset is 0: But ... I'm not sure how we'd test it :S |
Not sure how to test it, but omitting
https://www.postgresql.org/docs/9.0/static/queries-limit.html
|
Let's say we skipped the call to https://github.com/rmosolgo/graphql-ruby/compare/skip-offset-0 Would that actually be an improvement? When someone requested "page two", then offset would still be applied. Would cause the same issue described above? Also, GraphQL::Pro includes an alternate cursor implementation which uses column values as cursors instead of offsets, so you might check out that solution :P |
I guess GraphQL::Batch can be used as an approach that isn't subject to the If not, feel free to reopen this issue or open a new one with any details. |
Given the examples above, how would I optimize my resolver for all three? For example 2, I don't want to load the chat messages. For example 3, it would be nice to only select the fields I need from the database. Should I be introspecting the query from the resolver block to figure out what to do here?
The text was updated successfully, but these errors were encountered: