Search code examples
graphqlgqlgen

Pass Graphql input arguement to directive


I have a simple graphql query and a directive

directive @isOwner(postID: String!) on FIELD_DEFINITION

type Query {
  post(postID: String!): Post! @isOwner(postID: postID)
}

The problem is that I'm using GQLGen to generate my boilerplate code for Go, and directives are treated differently from the input values. This presents a unique challenge where authorization logic is almost isolated from the actual db reads, which makes the logic very inefficient, in that I have to eiither make a database read twice: during validation and the actual db read. The data required for validation is also required for the db read, and I would have to edit my whole code to inject this data into context. Is there a way of passing the input arguements dynamically to the directive and have the validation done dynamically and is it a good pracise in the first place?


Solution

  • Arguments passed to schema directives are evaluated when your schema is initially built, so they can't be dynamic. In this particular case, you don't need an argument at all -- you can just read the value of the field's arguments.

    visitFieldDefinition(field) {
      const { resolve = defaultFieldResolver } = field
      field.resolve = async function (parent, args, context, info) {
        console.log(args.postID)    
    
        return resolve.apply(this, [parent, args, context, info])
      }
    }
    

    However, if the name of the argument varies by field, then you can pass that as an argument to your directive

    directive @isOwner(argName: String!) on FIELD_DEFINITION
    
    visitFieldDefinition(field) {
      const { resolve = defaultFieldResolver } = field
      const { argName } = this.args
      field.resolve = async function (parent, args, context, info) {
        console.log(args[argName])    
    
        return resolve.apply(this, [parent, args, context, info])
      }
    }