Absinthe: How to import type modules in multiple other type modules

I have global enums and types defined in a type module, that are referenced as field types in other type modules.

For example, the global_types.ex has:

defmodule MyApp.Schema.GlobalTypes do
  use Absinthe.Schema.Notation

  enum :sort_order do
    value(:asc)
    value(:desc)
  end

which I use in two other type module files similar to:

posts_types.ex

defmodule MyApp.Schema.FooTypes do
  use Absinthe.Schema.Notation

  import_types(MyApp.Schema.GlobalTypes)

  object :posts_criteria do
    field(:filter, :posts_filter)
    field(:sort_order, :sort_order)

stores_types.ex

defmodule MyApp.Schema.BarTypes do
  use Absinthe.Schema.Notation

  import_types(MyApp.Schema.GlobalTypes)

  object :stores_criteria do
    field(:filter, :stores_filter)
    field(:sort_order, :sort_order)

When I do this, I get the following error:

Absinthe type identifier :sort_order is not unique.

References to types must be unique.

> All types within a GraphQL schema must have unique names. No two provided
> types may have the same name. No provided type may have a name which
> conflicts with any built in types (including Scalar and Introspection
> types).

How one know how to get around this? I’m using the latest absinthe beta:

defp deps do
    [
      {:absinthe, "~> 1.5.0-beta", override: true},

You only need to call import_types in the root module that does use Schema. We probably shouldn’t even import it in the notation modules. Think of the schema like one big namespace that all the types are eventually imported into. As long as they all get into the schema, the type validity checks will all work. Only call import_types from within the module you’re doing use Schema within.

6 Likes

Awesome. Thanks!
Creating these type modules that’ll be imported into different schemas, one that’s an admin schema exposing every single entity, and a general purpose schema that wouldn’t import certain type modules. So thought I had to resolve all references within the type schemas themselves. Appreciate the work on absinthe! Looking forward to documentation on some of the new features like SDL support.

Thanks! This is also the solution to a question I had, about circular import_types.

I wanted to do different modules for types which referenced one another, for example: you can get a list of comments from UserTypes and what user posted the comment from CommentTypes. And I thought I needed to import_types on both of them, but it caused the compiler to hung.

I haven’t been able to find a specific answer for that. Which is the same: only import_types in the root module that does use Schema.

This should be specified in the docs/guides/etc.

PR welcome!

1 Like