Skip to content

Commit

Permalink
Use absinthe directive macros instead of meta
Browse files Browse the repository at this point in the history
  • Loading branch information
kdawgwilk committed May 17, 2022
1 parent a8c828d commit fc6b6e3
Show file tree
Hide file tree
Showing 11 changed files with 109 additions and 160 deletions.
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ defmodule MyApp.MySchema do
+ use Absinthe.Federation.Schema

query do
+ extends()
+ directive :extends

field :review, :review do
arg(:id, non_null(:id))
Expand All @@ -62,12 +62,10 @@ defmodule MyApp.MySchema do
end

object :product do
+ key_fields("upc")
+ extends()
+ directive :key, fields: "upc"
+ directive :extends

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

field(:reviews, list_of(:review)) do
resolve(&ReviewResolver.get_reviews_for_product/3)
Expand Down
29 changes: 21 additions & 8 deletions lib/absinthe/federation/notation.ex
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,18 @@ defmodule Absinthe.Federation.Notation do
id: ID!
}
"""
defmacro key_fields(fields) when is_binary(fields) or is_list(fields) do
@deprecated "Use absinthe built in directive/2 macro"
defmacro key_fields(fieldset) when is_binary(fieldset) do
quote do
meta :key_fields, unquote(fields)
directive :key, fields: unquote(fieldset)
end
end

defmacro key_fields(fields) when is_list(fields) do
for fieldset <- fields do
quote do
directive :key, fields: unquote(fieldset)
end
end
end

Expand Down Expand Up @@ -75,9 +84,10 @@ defmodule Absinthe.Federation.Notation do
This type extension in the Reviews service extends the User type from the Users service.
It extends it for the purpose of adding a new field called reviews, which returns a list of `Review`s.
"""
@deprecated "Use absinthe built in directive/2 macro"
defmacro external() do
quote do
meta :external, true
directive :external
end
end

Expand Down Expand Up @@ -117,9 +127,10 @@ defmodule Absinthe.Federation.Notation do
to know the `email` of the `User` from the Users service in order to look up the `reviews`.
This means the `reviews` field / resolver requires the `email` field from the base `User` type.
"""
defmacro requires_fields(fields) when is_binary(fields) do
@deprecated "Use absinthe built in directive/2 macro"
defmacro requires_fields(fieldset) when is_binary(fieldset) do
quote do
meta :requires_fields, unquote(fields)
directive :requires, fields: unquote(fieldset)
end
end

Expand Down Expand Up @@ -164,9 +175,10 @@ defmodule Absinthe.Federation.Notation do
can provide it when going from review to product. `Product.name` is an external field
on an external type which is why the local type extension of `Product` and annotation of `name` is required.
"""
defmacro provides_fields(fields) when is_binary(fields) do
@deprecated "Use absinthe built in directive/2 macro"
defmacro provides_fields(fieldset) when is_binary(fieldset) do
quote do
meta :provides_fields, unquote(fields)
directive :provides, fields: unquote(fieldset)
end
end

Expand All @@ -188,9 +200,10 @@ defmodule Absinthe.Federation.Notation do
id: ID!
}
"""
@deprecated "Use absinthe built in directive/2 macro"
defmacro extends() do
quote do
meta :extends, true
directive :extends
end
end
end
1 change: 0 additions & 1 deletion lib/absinthe/federation/schema.ex
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ defmodule Absinthe.Federation.Schema do
def pipeline(pipeline) do
Pipeline.insert_after(pipeline, TypeImports, [
__MODULE__.Phase.AddFederatedTypes,
__MODULE__.Phase.AddFederatedDirectives,
__MODULE__.Phase.Validation.KeyFieldsMustExist,
__MODULE__.Phase.Validation.KeyFieldsMustBeValidWhenExtends
])
Expand Down
86 changes: 0 additions & 86 deletions lib/absinthe/federation/schema/phase/add_federated_directives.ex

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,15 @@ defmodule Absinthe.Federation.Schema.Phase.Validation.KeyFieldsMustExist do
object

true ->
key_fields = get_in(object.__private__, [:meta, :key_fields])
key_fields = object.directives
|> Enum.filter(fn %{name: name} -> name == "key" end)
|> Enum.map(fn
%{arguments: [%{input_value: %{content: %{value: fieldset}}}]} -> fieldset
%{arguments: [%{value: fieldset}]} -> fieldset
end)
# IO.inspect(object.directives, label: "object.directives")
# IO.inspect(key_fields, label: "key_fields")

validate_key_fields(key_fields, object, adapter)
end
end
Expand Down Expand Up @@ -82,7 +90,7 @@ defmodule Absinthe.Federation.Schema.Phase.Validation.KeyFieldsMustExist do
end

defp is_defining_or_extending?(object) do
not is_nil(get_in(object.__private__, [:meta, :key_fields]))
Enum.find_value(object.directives, false, fn %{name: name} -> name == "key" end)
end

defp in?(key, fields, adapter) do
Expand Down
26 changes: 26 additions & 0 deletions lib/absinthe/federation/schema/prototype.ex
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ defmodule Absinthe.Federation.Schema.Prototype do
"""
directive :key do
arg :fields, non_null(:_field_set)
arg :resolvable, :boolean, default_value: true
on [:object, :interface]
end

Expand Down Expand Up @@ -53,4 +54,29 @@ defmodule Absinthe.Federation.Schema.Prototype do
directive :extends do
on [:object, :interface]
end

@desc """
Indicates that an object type's field is allowed to be resolved by multiple subgraphs
(by default, each field can be resolved by only one subgraph).
"""
directive :shareable do
on [:field_definition, :object]
end

@desc """
Indicates that a field or type should be omitted from the gateway's API schema,
even if it's also defined in other subgraphs.
"""
directive :inaccessible do
on [:field_definition, :object_definition, :interface, :union]
end

@desc """
Indicates that a field is now resolved by this subgraph
instead of another subgraph where it's also defined.
"""
directive :override do
arg :from, non_null(:string)
on [:field_definition]
end
end
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ defmodule Absinthe.Federation.MixProject do

defp deps do
[
{:absinthe, "~> 1.6.5 or ~> 1.7.0"},
{:absinthe, path: "../../absinthe-graphql/absinthe"},
{:dataloader, "~> 1.0.9"},

# Dev
Expand Down
8 changes: 4 additions & 4 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
%{
"absinthe": {:hex, :absinthe, "1.6.6", "d4b3d87c868264edf47fbf9c152155f31e8d26c370607f5fe92f6e106d190b74", [:mix], [{:dataloader, "~> 1.0.0", [hex: :dataloader, repo: "hexpm", optional: true]}, {:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0 or ~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a03e18478b19bdf81ed1eef9b0853edf4496a080c2048ed17993dc945a90bedc"},
"dataloader": {:hex, :dataloader, "1.0.9", "8fb981e327fa692f741ab283ed93790203a6f6d412800f0f4f1531372e1dbf15", [:mix], [{:ecto, ">= 3.4.3 and < 4.0.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "6f8b7566c8dda46f53bdb336fd02f03f00bf58aeb6cc0f139ccdfd6f99d265a7"},
"absinthe": {:git, "https://github.com/absinthe-graphql/absinthe.git", "453fd12c0bbfd938c43a9251a320cfae96dafe16", [branch: "master"]},
"dataloader": {:hex, :dataloader, "1.0.10", "a42f07641b1a0572e0b21a2a5ae1be11da486a6790f3d0d14512d96ff3e3bbe9", [:mix], [{:ecto, ">= 3.4.3 and < 4.0.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:telemetry, "~> 1.0 or ~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "54cd70cec09addf4b2ace14cc186a283a149fd4d3ec5475b155951bf33cd963f"},
"dialyxir": {:hex, :dialyxir, "1.0.0", "6a1fa629f7881a9f5aaf3a78f094b2a51a0357c843871b8bc98824e7342d00a5", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "aeb06588145fac14ca08d8061a142d52753dbc2cf7f0d00fc1013f53f8654654"},
"earmark_parser": {:hex, :earmark_parser, "1.4.16", "607709303e1d4e3e02f1444df0c821529af1c03b8578dfc81bb9cf64553d02b9", [:mix], [], "hexpm", "69fcf696168f5a274dd012e3e305027010658b2d1630cef68421d6baaeaccead"},
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
"ex_doc": {:hex, :ex_doc, "0.25.3", "3edf6a0d70a39d2eafde030b8895501b1c93692effcbd21347296c18e47618ce", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "9ebebc2169ec732a38e9e779fd0418c9189b3ca93f4a676c961be6c1527913f5"},
"makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"},
"makeup_elixir": {:hex, :makeup_elixir, "0.15.1", "b5888c880d17d1cc3e598f05cdb5b5a91b7b17ac4eaf5f297cb697663a1094dd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "db68c173234b07ab2a07f645a5acdc117b9f99d69ebf521821d89690ae6c6ec8"},
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
"nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"},
"telemetry": {:hex, :telemetry, "0.4.3", "a06428a514bdbc63293cd9a6263aad00ddeb66f608163bdec7c8995784080818", [:rebar3], [], "hexpm", "eb72b8365ffda5bed68a620d1da88525e326cb82a75ee61354fc24b844768041"},
"nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"},
"telemetry": {:hex, :telemetry, "1.1.0", "a589817034a27eab11144ad24d5c0f9fab1f58173274b1e9bae7074af9cbee51", [:rebar3], [], "hexpm", "b727b2a1f75614774cff2d7565b64d0dfa5bd52ba517f16543e6fc7efcc0df48"},
}
59 changes: 42 additions & 17 deletions test/absinthe/federation/notation_test.exs
Original file line number Diff line number Diff line change
@@ -1,29 +1,54 @@
defmodule Absinthe.Federation.NotationTest do
use Absinthe.Federation.Case, async: true

describe "macro schema" do
defmodule MacroSchema do
use Absinthe.Schema
use Absinthe.Federation.Schema
defmodule FederatedMacroSchema do
use Absinthe.Schema
use Absinthe.Federation.Schema

query do
field :me, :user
end
query do
field :me, :user
end

object :user do
key_fields("id")
extends()
object :user do
key_fields("id")
extends()

field :id, non_null(:id) do
external()
end
field :id, non_null(:id) do
external()
end
end
end

test "can use federation macros" do
sdl = Absinthe.Schema.to_sdl(MacroSchema)
assert sdl =~ "type User @extends @key(fields: \"id\")"
assert sdl =~ "id: ID! @external"
test "can use federation macros" do
sdl = Absinthe.Schema.to_sdl(FederatedMacroSchema)
assert sdl =~ "type User @extends @key(fields: \"id\")"
assert sdl =~ "id: ID! @external"
end

defmodule AbsintheMacroSchema do
use Absinthe.Schema
use Absinthe.Federation.Schema

query do
field :me, :user
end

object :user do
directive :key, fields: "id"
directive :extends

field :id, non_null(:id) do
directive :external
end

field :name, :string, directives: [:provides]
end
end

test "can use absinthe directive macros" do
sdl = Absinthe.Schema.to_sdl(AbsintheMacroSchema)
assert sdl =~ "type User @extends @key(fields: \"id\")"
assert sdl =~ "id: ID! @external"
assert sdl =~ "name: String @provides"
end
end
34 changes: 0 additions & 34 deletions test/absinthe/federation/schema/directive_test.exs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ defmodule Absinthe.Federation.Schema.KeyFieldsMustExistTest do
end

test "it should throw an error when flat key fields not exist" do
assert %{phase_errors: [error2, error1]} = catch_error(Code.eval_string(@flat_key_schema))
assert %{phase_errors: [error1, error2]} = catch_error(Code.eval_string(@flat_key_schema))
assert %{message: "The @key \"productUuid\" does not exist in :product object.\n"} = error1
assert %{message: "The @key \"name\" does not exist in :product object.\n"} = error2
end
Expand Down

0 comments on commit fc6b6e3

Please sign in to comment.