graphql-batch icon indicating copy to clipboard operation
graphql-batch copied to clipboard

Add example of a custom non-record-loading loader

Open hidde-jan opened this issue 7 years ago • 3 comments

In the README, a CountLoader example is named, but it's not particularly detailed:

CountLoader.for(Shop, :smart_collections).load(context.shop_id),
CountLoader.for(Shop, :custom_collections).load(context.shop_id),

A clear example that demonstrates "You can also batch other stuff, not only load records from a DB" could be very helpful for new users. A great example would be something that does a HTTP request to some external API, combining two non-record-from-db-loading use cases.

hidde-jan avatar Jul 16 '18 13:07 hidde-jan

I've been using the Record loader a lot, but run into a couple of problems that I haven't been able to figure out; I would love some more documentation on things like:

  • Is it possible to maintain order after the promises are fulfilled?
  • Can we batch HABTMs?

Amnesthesia avatar Oct 16 '18 19:10 Amnesthesia

Hey, @hidde-jan, @Amnesthesia . CountLoader is just something like other loaders. The most important thing you have to do is to implement perform method . In the user-defined perform method, you have to create some key-value s by input keys using fulfill like this example. Here is the general usage

  • define your loader class and,
  • implement initialize, usually with some arguments you need and,
  • implement perform. In this method you have to get all results by keys, and create your key-value s

This example is far from ActiveRecord or any ORM

class MyLoader < GraphQL::Batch::Loader

  def initialize(arguments)
    @arguments = arguments
  end

  # Usually you don't have to implement your method unless some type casts are different
  def load(key)
    super(key)
  end

  # As it is refered from "You can also batch other stuff, not only load records from a DB"
  # In this example result is an object with attr `key`. Possiblly it is a redis obejct, json or rpc result defined in get_results
  def perform(keys)
    results = get_results(keys)

    results.each { |result| fulfill(result.key, result)} 

    keys.each { |key| fulfill(key, nil) unless fulfilled?(key) }
  end

  private

  def get_results(keys)
    #  your implementation, remember to return an array
  end
end

razertory avatar Nov 12 '18 14:11 razertory

There's an example of a CountLoader and some other loaders here: https://github.com/jamesbrooks/graphql-batch-loaders

ronocod avatar Nov 15 '21 17:11 ronocod