Absinthe: Is there a way to reuse args for different fields?

Created on 13 Aug 2017  路  3Comments  路  Source: absinthe-graphql/absinthe

hey, I'm new to elixir/phoenix/absinthe (this is my first time using either) so I apologize if this is something that should be very obvious.

In my schema I have many fields which resolve to a simple paginatable list:

...
field :tags, list_of(:tag) do
    arg :offset, :integer, default_value: 0
    arg :limit, :integer, default_value: 20
    resolve &App.Resolver.Tag.find_from_parent/3
end
field :posts, list_of(:post) do
    arg :offset, :integer, default_value: 0
    arg :limit, :integer, default_value: 20
    resolve &App.Resolver.Post.find_from_parent/3
end
...

Is there a way to reuse the args lines, so that I could just do something along these lines of this:

...
field :tags, list_of(:tag) paginatable(App.Resolver.Tag.find_from_parent/3)
field :posts, list_of(:post), paginatable(App.Resolver.Post.find_from_parent/3)
...

or even something like paginatable_assoc(:posts) similar to the absinthe-ecto assoc function, but with args?

It just seems like I'm writing a lot of repeat code so far. I'm sure there must be a better a way.

Also if anyone has a real project built with absinthe on github that would be so helpful (or even just a real world schema example). The example project is quite simple and seems like it's outdated, and even the tutorial on the absinthe website seems outdated (e.g. it says the absinthe-ecto project is "coming soon")

Regardless this project is great, and I really appreciate all of your work on it.

Thanks!

Most helpful comment

@benwilson512 this is still the top result about absinthe and pagination.. did you ever put something more formal into absinthe? I can't find anything on pagination on hexdocs at least

All 3 comments

Hey! Always glad to have new folks in the community.

You're right to observe that our online guides are a bit out of date, unfortunately all the effort we've been putting into the book has left little time to update them. We plan to do so after the book hits beta on September 6th.

To your point, here's the best solution at the moment, and then a few words about de-duplication in schemas:

defmodule MyApp.Web.Helpers do
  defmacro pagination_args() do
    quote do
      arg :offset, :integer, default_value: 0
      arg :limit, :integer, default_value: 20
    end
  end
end

# in your schema module
import MyApp.Web.Helpers
# in a query object
field :posts, list_of(:page) do
  pagination_args()
  arg :some_specific_filter
  resolve &blah/3
end

Through the additional use of macros you could probably build something close to what you have there, probably by doing like paginated field :posts, list_of(:post) or something like that.

Frankly, it isn't the most ergonomic and we know that, there are some real limitations to building flexible schemas at the moment due to how the macro based system works. We have some planned changes that'll be in Absinthe 1.5 but that at this point is still a ways away.

Finally though a general note on "duplication". In this case I think it's handy to extract these common args because they're basically all part of a common interface. There are other situations however which while it feels like duplication at first, as time goes on what you're getting with the extra bit of typing is the freedom to easily adapt each field to the needs of the client without coupling the behaviour to other fields.

Be careful about premature efforts to DRY out schemas.

@benwilson512 this is still the top result about absinthe and pagination.. did you ever put something more formal into absinthe? I can't find anything on pagination on hexdocs at least

Any pointers on pagination? @benwilson512

Was this page helpful?
0 / 5 - 0 ratings