jlouis / graphql-erlang

GraphQL implementation in Erlang.
Other
313 stars 52 forks source link

Field directive hook idea #191

Closed tudborg closed 5 years ago

tudborg commented 5 years ago

Not happy with the actual implementation here, but I wanted to evaluate the idea.

When executing a field with field directives, you have the option of specifying a middleware-like construct around the field resolution. Each directive can have it's own resolver module, just like resolving objects, scalars, etc.

The directive resolver takes the standard Ctx, Obj, Field, Args (right now at least), and then Directive and Resolver, where directive is the formattet #directive{} record and Resolver is the field resolver function that you are expected to call when you have handle your directive-specific logic.

tudborg commented 5 years ago

The relevant parts:

mapping_rules() ->
    #{
       % ....
       unions => #{ default => dungeon_type },
       directives => #{ default => dungeon_directive }, % here
       objects => #{
        % ....
     }.

The directive execution:

-module (dungeon_directive).
-include_lib("graphql/include/graphql.hrl").

-export ([execute/6]).

execute(Ctx, Obj, Field, Args, #directive{} = _Directive, Resolver) ->
    Resolver(Ctx, Obj, Field, Args).

and in the schema, any directive will do:

type Monster implements Node {
  # ...
  inventory : [Thing] @alwaysError(reason: "custom directive test")
  # ...
}
tudborg commented 5 years ago

I want to expand this so that all (schema) directives on something that can be resolved will have the option to be called in this way, so ease implementing things like authorization, deprecation error, etc.

tudborg commented 5 years ago

Closing in favor of #192