Closed SeanRoberts closed 6 years ago
https://github.com/rmosolgo/graphql-ruby/issues/1324 mentions https://github.com/rmosolgo/graphql-ruby/blob/master/guides/type_definitions/extensions.md which describes how one could implement it
Hey there,
I'm working with a policy object, but after changing my types to class-based syntax, the object doesn't work anymore too..
@exAspArk are you planning to adapt graphql-guard
to the new class-based syntax?
Thanks for your efforts!
As described in GraphQL - Extending the GraphQL-Ruby Type Definition System, extending GraphQL::Schema::Field
works when using inline policies:
# app/graphql/fields/guardable.rb
class Fields::Guardable < GraphQL::Schema::Field
def initialize(*args, guard:, **kwargs, &block)
@guard = guard
super *args, **kwargs, &block
end
def to_graphql
field_defn = super
field_defn.tap { |d| d.metadata[:guard] = @guard }
end
end
# app/graphql/types/query.rb
class Types::Query < Types::BaseObject
field_class Fields::Guardable
field :viewer, Types::User, guard: ->(obj, args, ctx) { !ctx[:current_user].nil? }
def viewer
context[:current_user]
end
end
I noticed that accepts_definition
is also useful for inline guards:
# app/graphql/fields/guardable.rb
class Fields::Guardable < GraphQL::Schema::Field
accepts_definition :guard
end
# app/graphql/types/query.rb
class Types::Query < Types::BaseObject
field_class Fields::Guardable
field :viewer, Types::User do
guard ->(obj, args, ctx) { !ctx[:current_user].nil? }
end
def viewer
context[:current_user]
end
end
ref: http://graphql-ruby.org/type_definitions/extensions.html#customization-compatibility
@kymmt90 fixed it in https://github.com/exAspArk/graphql-guard/pull/17. I released the changes in version 1.2.0
:)
@kymmt90 could you make the accepts_definition
work? The first version is working for me:
class Fields::Authenticable < GraphQL::Schema::Field
def initialize(*args, authenticate: false, **kwargs, &block)
@authenticate = authenticate
super(*args, **kwargs, &block)
end
def to_graphql
field_defn = super
field_defn.metadata[:authenticate] = @authenticate
field_defn
end
end
field :vehicles, Types::VehicleType.connection_type, null: false, authenticate: true do
argument :orderBy, String, 'id', required: false
end
but the accepts_definition
is not :(.
class Fields::Authenticable < GraphQL::Schema::Field
accepts_definition :authenticate
end
field :vehicles, Types::VehicleType.connection_type, null: false do
authenticate ->(obj, args, ctx) { ctx[:current_user].nil? }
argument :orderBy, String, 'id', required: false
end
It says GraphQL::Field can't define 'authenticate'
In case of authentication doesn't really matter but for authorization where I wanna pass in policies I would prefer the second option.
@RealSilo not sure where the authenticate
came from? On a field level, with graphql-guard
, you should either use guard
or mask
.
If you'd like to add your custom definition, please try to find more information on graphql-ruby.org.
I am trying to implement a custom method (authenticate), but can't figure it out with the new class based syntax (I checked the docs). If you happen to have some example it would be great. Here is the old syntax: https://medium.com/impraise-design-engineering/generic-authorization-with-graphql-and-ruby-11f61f24c60b that I am trying to implement with the new class based syntax. In this example it's authorization instead of authentication but the pattern is the same.
graphql-ruby 1.8 is introducing a new class-based syntax, however it seems to break compatibility with graphql-guard.
results in
undefined method 'guard' for GraphQL::Schema::Field
Is there a potential workaround (aside from just not using the new syntax)?