README.md in graphql_preload_queries-0.1.0 vs README.md in graphql_preload_queries-0.2.0
- old
+ new
@@ -1,78 +1,65 @@
-# GraphqlPreloadQueries (In progress)
-This gem helps to define all possible preloads for graphql data results and avoid the common problem "N+1 Queries".
+# GraphqlPreloadQueries
+This gem helps you to define all nested preloads to be added when required for graphql data results and avoid the common problem "N+1 Queries".
## Usage
- * Preloads in query results
+ * Object Type
```ruby
- # queries/articles.rb
- def articles
- resolve_preloads(Article.all, { allComments: :comments })
- end
+ class UserType < Types::BaseObject
+ add_preload 'parents|allParents', { preload: :parents, friends: :friends, parents: :parents }
+ add_preload :friends, { parents: { preload: :parents, parents: :parents, friends: :friends } }
+
+ field :id, Int, null: true
+ field :name, String, null: true
+ field :friends, [Types::UserType], null: false
+ field :parents, [Types::UserType], null: false
+ end
```
- When articles query is performed and:
- * The query includes "allComments", then ```:comments``` will automatically be preloaded
- * The query does not include "allComments", then ```:comments``` is not preloaded
+ Examples:
+ * ```add_preload :friends```
+ ```:friends``` association will be preloaded if query includes ```friends```, like: ```user(id: 10) { friends { ... } }```
- * Preloads in mutation results
+ * ```add_preload :allFriends, :friends```
+ ```:friends``` association will be preloaded if query includes ```allFriends```, like: ```user(id: 10) { allFriends { ... } }```
+
+ * ```add_preload :allFriends, { preload: :friends, parents: :parents }```
+ ```:preload``` key can be used to indicate the association name when defining nested preloads, like: ```user(id: 10) { allFriends { id parents { ... } } }```
+
+ * ```add_preload :friends, { allParents: :parents }```
+ (Nested 1 lvl preloading) ```friends: :parents``` association will be preloaded if query includes ```allParents```, like: ```user(id: 10) { friends { allParents { ... } } }```
+
+ * ```add_preload :friends, { allParents: { preload: :parents, friends: :friends } }```
+ (Nested 2 levels preloading) ```friends: { parents: :friends }``` association will be preloaded if query includes ```friends``` inside ```parents```, like: ```user(id: 10) { friends { allParents { { friends { ... } } } } }```
+
+ * ```add_preload 'friends|allFriends', :friends```
+ (Multiple gql queries) ```:friends``` association will be preloaded if query includes ```friends``` or ```allFriends```, like: ```user(id: 10) { friends { ... } }``` OR ```user(id: 10) { allFriends { ... } }```
+
+ * ```add_preload 'ignoredFriends', 'ignored_friends.user'```
+ (Deep preloading) ```{ ignored_friends: :user }``` association will be preloaded if query includes ```inogredFriends```, like: ```user(id: 10) { ignoredFriends { ... } }```
+
+ * Preloads in query results
```ruby
- # mutations/articles/approve.rb
- def resolve
- affected_articles = Article.where(id: [1,2,3])
- res = resolve_preloads(affected_articles, { allComments: :comments })
- { articles => res }
+ # queries/users.rb
+ def user(id:)
+ user = include_gql_preloads(:user, User.where(id: id))
end
```
- When approve mutation is performed and:
- * The result articles query includes "allComments", then ```:comments``` will automatically be preloaded
- * The result articles query does not include "allComments", then ```:comments``` is not preloaded
+ - include_gql_preloads: Will preload all preloads configured in UserType based on the gql query.
- * Preloads in ObjectTypes
+ * Preloads in mutation results
```ruby
- # types/article_type.rb
- module Types
- class ArticleType < Types::BaseObject
- preload_field :allComments, [Types::CommentType], preload: { owner: :author }, null: false
- end
+ # mutations/users/disable.rb
+ #...
+ field :users, [Types::UserType], null: true
+ def resolve(ids:)
+ affected_users = User.where(id: ids)
+ affected_users = include_gql_preloads(:users, affected_users)
+ puts affected_users.first&.friends
+ { users: affected_users }
end
```
- When any query is retrieving an article data and:
- * The query includes ```owner``` inside ```allComments```, then ```:author``` will automatically be preloaded inside "allComments" query
- * The query does not include ```owner```, then ```:author``` is not preloaded
- This field is exactly the same as the graphql field, except that this field expects for "preload" setting which contains all configurations for preloading
+ - include_gql_preloads: Will preload all preloads configured in UserType based on the gql query.
- Complex preload settings
- ```ruby
- # category query
- {
- 'posts' =>
- [:posts, # :posts preload key will be used when: { posts { id ... } }
- {
- 'authors|allAuthors' => [:author, { # :author key will be used when: { posts { allAuthors { id ... } } }
- address: :address # :address key will be used when: { posts { allAuthors { address { id ... } } } }
- }],
- history: :versions # :versions key will be used when: { posts { history { ... } } }
- }
- ],
- 'disabledPosts' => ['category_disabled_posts.post', { # :category_disabled_posts.post key will be used when: { disabledPosts { ... } }
- authors: :authors # :authors key will be used when: { disabledPosts { authors { ... } } }
- }]
- }
- ```
- * ```authors|allAuthors``` means that the preload will be added if "authors" or "allAuthors" is present in the query
- * ```category_disabled_posts.post``` means an inner preload, sample: ```posts.preload({ category_disabled_posts: :post })```
-
-### Important:
- Is needed to omit "extra" params auto provided by Graphql when using custom resolver (only in case not using params), sample:
- ```ruby
- # types/post_type.rb
- preload_field :allComments, [Types::CommentType], preload: { owner: :author }, null: false
- def allComments(_omit_gql_params) # custom method resolver that omits non used params
- object.allComments
- end
- ```
-
-
## Installation
Add this line to your application's Gemfile:
```ruby
gem 'graphql_preload_queries'