Absinthe fields from a list?

I’m trying to replace my hardcoded list of fields for an absinthe object with an elixir list. Here is my attempt, which doesn’t work:

use Absinthe.Schema.Notation

object :obj do
  Enum.each([:a, :b, :c], fn(p) ->
    field(p, non_null(:boolean))
  end)
end

I get

(ArgumentError) argument error
:erlang.atom_to_binary({:p, [line: 255], nil}, :utf8)

when trying to compile.

Not sure how I could solve this?

As background on why I need this: In our system, we have a list of permissions a user can have. This list is currently duplicated in ecto fields, in views, in other parts of the system that need to know all permissions and in our GraphQL schema. I’m trying to get rid of this code duplication, maintain one list of atoms. Maybe there is an even better way?

So the schema dsl is comprised of macros, including ‘field’, which may be why this doesn’t work as expected.

You could experiment with writing a macro that produces those field definitions and see if that does the trick (that’s what I’ve done in the past for similar-but-different needs)

As an aside, if there are multiple GraphQL objects that need the same fields you can use import_fields: Importing Fields — absinthe v1.6.2 but it sounds like you’re after an abstraction that extends further than just your schema, so it may not be useful.

That’s what a colleague suggested as well. We tried it and it works, although I’m not 100% happy with the solution. But it’s way cleaner than having the list of permissions duplicated.

Thanks for pointing out importing fields. I think I can use this one for a little cleaning up at other points in our GraphQL API.

Take a look at: Custom Schema Manipulation

You can generate anything you want using it. At start you have more code, but in longer term you would notice how much more features it has comparing to simple loops.

1 Like