absinthe-graphql / absinthe

The GraphQL toolkit for Elixir
http://absinthe-graphql.org
Other
4.29k stars 530 forks source link

Cannot import shared fields #385

Closed nitingupta910 closed 6 years ago

nitingupta910 commented 7 years ago

I have a set of shared fields defined in shared.ex:

object :shared do
   # shared fields
end

and two object types, defined in foo.ex and bar.ex which want to import fields in this shared object:

foo.ex

use Absinthe.Schema.Notation

import_types Shared

object :foo do
  import_fields :shared
end

bar.ex

use Absinthe.Schema.Notation

import_types Shared

object :bar do
  import_fields :shared
end

and finally in schema.ex:

use Absinthe.Schema

import_types KnowledgeGraph.Types.Foo
import_types KnowledgeGraph.Types.Bar

query do
  field :foo, type: :foo
  field :bar, type: :bar
end

With this setup, I'm getting this build error:

schema.ex: Absinthe type identifier :shared is not unique.

So, the question is, how do I keep fields shared between foo and bar in a separate file?

Setup details:

mix deps | grep absinthe

* absinthe 1.4.0-beta.5 (Hex package) (mix)
  locked at 1.4.0-beta.5 (absinthe) 63e04147
* absinthe_plug 1.4.0-beta.2 (Hex package) (mix)
  locked at 1.4.0-beta.2 (absinthe_plug) c30bc0cb

elixir --version
Erlang/OTP 20 [erts-9.0] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]

Elixir 1.5.1
bruce commented 7 years ago

Try moving all of your import_types to schema.ex; type resolution doesn't happen until compilation and imports aren't done inside type (non schema) modules. We're going to work on making this more clear in a future release.

nitingupta910 commented 7 years ago

I now moved all imports in schema.ex:

  import_types Shared
  import_types Foo
  import_types Bar

and removed import of shared in foo and bar. Now it compiles fine. However, graphiql cannot see any shared field from either foo or bar:

query Foo {
  foo(id: "123") {
    fshared  <---- field defined on shared object but not visible in foo which import_fields :shared
    ffoo
  }
}
benwilson512 commented 7 years ago

Can you supply your object :foo definition?

nitingupta910 commented 7 years ago
object :foo do
    import_fields :shared

    field :ffoo, :string do
      resolve fn _, _, _ -> {:ok, "ffoo value"} end
    end
end

just for reference, here is object :shared:

  object :shared do
    field :id, :id

    field :fshared, :string do
      resolve fn _, _, _ -> {:ok, "fshared value"} end
    end
  end
benwilson512 commented 7 years ago

You're going to need to provide the actual code the causes the issue, or at least a simplified example that actually demonstrates the issue. Using the code you've provided doesn't exhibit any problem at all:

defmodule Shared do
  use Absinthe.Schema.Notation

  object :shared do
    field :id, :id

    field :fshared, :string do
      resolve fn _, _, _ -> {:ok, "fshared value"} end
    end
  end
end

defmodule Schema do
  use Absinthe.Schema

  import_types Shared

  object :foo do
    import_fields :shared

    field :ffoo, :string do
      resolve fn _, _, _ -> {:ok, "ffoo value"} end
    end
  end

  query do
    field :foo, :foo, resolve: fn _, _, _ -> {:ok, %{}} end
  end
end

Absinthe.run("{foo { fshared }}", Schema)
#=> {:ok, %{data: %{"foo" => %{"fshared" => "fshared value"}}}}
nitingupta910 commented 7 years ago

I created git repo for a minimal running absinthe project which reproduces this issue: absinthe_385

Here is some iex output:

iex(9)> Absinthe.run("{foo { ffoo }}", Schema)    
{:ok, %{data: %{"foo" => %{"ffoo" => "ffoo value"}}}}

iex(10)> Absinthe.run("{foo { ffshared }}", Schema)
{:ok,
 %{errors: [%{locations: [%{column: 0, line: 1}],
      message: "Cannot query field \"ffshared\" on type \"Foo\"."}]}}
iex(11)> 
benwilson512 commented 7 years ago

Awesome, I'll take a look here as soon as I can.

nitingupta910 commented 7 years ago

I just removed some more code to make the example simpler.

benwilson512 commented 7 years ago

Hey! Confirmed that this is indeed an issue. Basically, import_fields doesn't work unless the object you're importing from is defined in the module, or imported into the module. Obviously that won't work if you want to have it imported in several places.

Will fix.

xtian commented 7 years ago

@benwilson512 Any update on this? I’m running into this issue as well.

I’d be happy to put together a PR if you can point me in the right direction for the fix. :)

bruce commented 7 years ago

@benwilson512 I feel like we've ran into this before. Is this something @xtian can pick up (if still interested), or do you need to do a deeper dive?

Yamilquery commented 6 years ago

Any update on this? How can I use shared fields? I would like to avoid duplicate fields.

benwilson512 commented 6 years ago

Hey. I think in the current implementation of the schema this is not possible right now. The Absinthe 1.5 release will include a full re-work of the schema internals, and I think this will be possible then.

benwilson512 commented 6 years ago

This works now in 1.5 / master.