pwightman

pwightman

How to access schema information during Ecto query generation when using Absinthe/Dataloader?

Hi, I’m using Absinthe with Dataloader and have a question.

Here’s some code that mimics the example from the tutorial very closely (found here), all the usual suspects:

defmodule MyApp.Schema do
  # ...
  object :post do
    field :title, :string
  end

  object :author do
    field :posts, list_of(:post) do
      arg(:limit, :integer)
      resolve(dataloader(MyApp.Blog))
    end
  end

  def context(ctx) do
    loader =
      Dataloader.new()
      |> Dataloader.add_source(MyApp.Blog, MyApp.Blog.data())

    Map.put(ctx, :loader, loader)
  end

  def plugins do
    [Absinthe.Middleware.Dataloader] ++ Absinthe.Plugin.defaults()
  end
end

And then MyApp.Blog:

defmodule MyApp.Blog do
  # ...
  def data() do
    Dataloader.Ecto.new(MyApp.Repo, query: &query/2)
  end

  def query(queryable, params) do
    # How can I get params[:limit] to be the :limit arg from the schema???
    queryable
    |> limit(params[:limit] || 20)
  end
end

My question is: how can I access the limit arg attached to the posts field on author from the Schema, such that I can use an Ecto limit query inside MyApp.Blog.query/2? I can see in the docs that you can pass params along to the query function by passing them along in the Dataloader.load call, but from what I can tell, that is called internally.

Is there a way to pass the limit arg through that doesn’t involve abandoning dataloader and falling back to the raw batch function?

Thanks for any help!

Marked As Solved

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

Hey @pwightman. To start with, the load function is not private or internal, it’s the main API for Dataloader itself. The dataloader/1 helper is great, and covers a lot of main use cases, but in certain complex scenarios using load/4 directly is perfectly fine.

The dataloader/1 helper actually passes along all arguments the resolver has to the query function, so you should actually see limit in there already, have you looked for it?

Unfortunately though, using a limit here is probably not what you want. limit when applied to an SQL query applies to the total number of result rows, whereas the meaning or authors { posts(limit: 20) } would normally be “20 posts per author”.

To limit the way you want requires window functions, which are not yet supported out of the box by dataloader. You can find some discussion of this here: https://github.com/absinthe-graphql/absinthe_relay/issues/128 This is specifically about relay connection queries but the principle is the same.

Also Liked

pwightman

pwightman

Ah, very true. Mostly I was using this as an example of passing arbitrary values to fields, accessing the schema generally, etc, but I had forgotten about this issue with limit specifically.

I feel a little like I’m going crazy, but yes, it turns out query/2 does receive all args already, I checked this specifically last night before posting and could have sworn it wasn’t, but upon checking again this morning, there they are.

Digging a bit, I was also happy to find there’s a dataloader/3 with all sorts of useful information in it as well, so should be able to access everything I need.

Thanks for all your work on Absinthe, really enjoying it!

Where Next?

Popular in Questions Top

Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
logicmason
Hi there, I'm working through my first release with elixir/phoenix. I've built a release with distillery and found that it crashes when I...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> someth...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
William
I would like to know that is there any online source for learning Phoenix Framework for building E-Commerce Store? Any advantage on build...
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
Nvim
Elixir appears to be a superior language to Python. I don’t see any advantage of Python over Elixir. Are there any?
New

We're in Beta

About us Mission Statement