N1Loader is designed to supply a easy method for avoiding N+1 points
of any variety. Gladly, it is tremendous simple to combine along with your GraphQL
API. Without additional delay, let’s take a look at a easy however but detailed
instance.
# Add N1Loader with ArLazyPreload integration
require "n1_loader/ar_lazy_preload"
require 'graphql'
# Setup SQLite tables in reminiscence. That is irrelevant to the instance.
require_relative 'context/setup_database'
# ArLazyPreload requires Rails software. This is required to keep away from that.
require_relative 'context/setup_ar_lazy'
class User < ActiveRecord::Base
has_many :funds
n1_optimized :payments_total do |customers|
# Fetch funds for a gaggle of customers we are going to preload in a single question
total_per_user = Payment.group(:user_id).the place(person: customers).sum(:quantity).faucet h
customers.every do |person|
complete = total_per_user[user.id]
# No guarantees right here, merely add a worth for to a person.
fulfill(person, complete)
finish
finish
finish
class Payment < ActiveRecord::Base
belongs_to :person
validates :quantity, presence: true
finish
# Enable ArLazyPreload globally
ArLazyPreload.config.auto_preload = true
# Or use +preload_associations_lazily+ when loading objects from database
class UserKind < GraphQL::Schema::Object
subject :payments_total, Integer
finish
class QueryType < GraphQL::Schema::Object
subject :customers, [UserType]
def customers
User.all
finish
finish
class Schema < GraphQL::Schema
question QueryType
finish
query_string = <<~GQL
{
customers {
paymentsTotal
}
}
GQL
# No N+1. And by no means shall be!
p Schema.execute(query_string)['data']
N1Loader helps arguments which you can go via GraphQL API. There will no N+1 nonetheless.
class User < ActiveRecord::Base
n1_optimized :payments_total do
argument :from
argument :to
def carry out(customers)
total_per_user =
Payment
.group(:user_id)
.the place(created_at: from..to)
.the place(person: customers)
.sum(:quantity)
.faucet h
customers.every do |person|
complete = total_per_user[user.id]
fulfill(person, complete)
finish
finish
finish
finish
class UserKind < GraphQL::Schema::Object
subject :payments_total, Integer do
argument :from, Time
argument :to, Time
finish
finish
query_string = <<~GQL
{
customers {
paymentsTotal
}
}
GQL
# No N+1. And by no means shall be!
p Schema.execute(query_string, variables: {from: 3.days.in the past, to: 1.day.in the past})['data']
Define loaders as soon as – use it in every single place with out N+1.
Check N1Loader for extra options and provides it a attempt in your initiatives.