Skip to content

Adds Apollo Federation Spec conformance to the absinthe GraphQL library

License

Notifications You must be signed in to change notification settings

Frameio/absinthe_federation

 
 

Repository files navigation

Absinthe.Federation

Build Status Hex pm Hex Docs License

Apollo Federation support for Absinthe

Installation

Install from Hex.pm:

def deps do
  [
    {:absinthe_federation, "~> 0.5"}
  ]
end

Install from github:

def deps do
  [
    {:absinthe_federation, github: "DivvyPayHQ/absinthe_federation", branch: "main"}
  ]
end

Add the following line to your absinthe schema

defmodule MyApp.MySchema do
  use Absinthe.Schema
+ use Absinthe.Federation.Schema

  query do
    ...
  end
end

Usage

Macro based schemas (recommended)

Note: Implementing the reference resolver with function capture does not work at the moment. Hence, the below example uses an anonymous function.

defmodule MyApp.MySchema do
  use Absinthe.Schema
+ use Absinthe.Federation.Schema

  query do
+   extends()

    field :review, :review do
      arg(:id, non_null(:id))
      resolve(&ReviewResolver.get_review_by_id/3)
    end
    ...
  end

  object :product do
+   key_fields("upc")
+   extends()

    field :upc, non_null(:string) do
+     external()
    end

    field(:reviews, list_of(:review)) do
      resolve(&ReviewResolver.get_reviews_for_product/3)
    end

+   field(:_resolve_reference, :product) do
+     resolve(fn parent, args, context ->
        ProductResolver.get_product_by_upc(parent, args, context)
      end)
+   end
  end
end

Macro based schema with existing prototype

If you are already using a schema prototype

defmodule MyApp.MySchema do
  use Absinthe.Schema
+ use Absinthe.Federation.Schema, prototype_schema: MyApp.MySchemaPrototype

  query do
    ...
  end
end
defmodule MyApp.MySchemaPrototype do
  use Absinthe.Schema.Prototype
+ use Absinthe.Federation.Schema.Prototype.FederatedDirectives

  directive :my_directive do
    on [:schema]
  end
end

SDL based schemas (experimental)

defmodule MyApp.MySchema do
  use Absinthe.Schema
+ use Absinthe.Federation.Schema

  import_sdl """
    extend type Query {
      review(id: ID!): Review
    }

    extend type Product @key(fields: "upc") {
      upc: String! @external
      reviews: [Review]
    }
  """

  def hydrate(_, _) do
    ...
  end

Resolving structs in _entities queries

If you need to resolve your struct to a specific type in your schema you can implement the Absinthe.Federation.Schema.EntityUnion.Resolver protocol like this:

defmodule MySchema do
  @type t :: %__MODULE__{
          id: String.t()
        }

  defstruct id: ""

  defimpl Absinthe.Federation.Schema.EntityUnion.Resolver do
    def resolve_type(_, _), do: :my_schema_object_name
  end
end

Federation v2

You can import Apollo Federation v2 directives by extending your top-level schema with the @link directive.

defmodule MyApp.MySchema do
  use Absinthe.Schema
  use Absinthe.Federation.Schema

+ extend schema do
+   directive :link,
+     url: "https://specs.apollo.dev/federation/v2.0",
+     import: [
+       "@key",
+       "@shareable",
+       "@provides",
+       "@external",
+       "@tag",
+       "@extends",
+       "@override",
+       "@inaccessible"
+     ]
+ end

  query do
    ...
  end
end

Namespacing and directive renaming with @link

@link directive supports namespacing and directive renaming (only on Absinthe >= 1.7.2) according to the specs.

defmodule MyApp.MySchema do
  use Absinthe.Schema
  use Absinthe.Federation.Schema

+ extend schema do
+   directive :link,
+     url: "https://specs.apollo.dev/federation/v2.0",
+     import: [%{"name" => "@key", "as" => "@primaryKey"}], # directive renaming
+     as: "federation" # namespacing
+ end

  query do
    ...
  end
end

More Documentation

See additional documentation, including guides, in the Absinthe.Federation hexdocs.

Contributing

Refer to the Contributing Guide.

License

See LICENSE

About

Adds Apollo Federation Spec conformance to the absinthe GraphQL library

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Elixir 100.0%