0
votes

I am using Apollo GraphQL server and directives.

Here is my simple schema. Notice the directive on the token field, User type.

const typeDefs = `
directive @allow(service: String) on FIELD_DEFINITION 

type User {
  email: String!
  pass: String!
  ... other fields here
  token: String  @allow(service: "login")
}

type Mutation {
  login(email: String!, pass: String!): User
}`;

I would like to return the token field only if the login has been called. Otherwise, I would like to return the User object without the token field, all I could find is throwing an Exception or returning the null in the "token" field.

class SkipDirective extends SchemaDirectiveVisitor {
  visitFieldDefinition(field, details) {
    const { resolve = defaultFieldResolver } = field;
    field.resolve = async function (...args) {
      // If called in context different from "login"
      // Here I would like to just "delete" the "token" field
      else {
        const result = await resolve.apply(this, args);
        return result;
      }
    };
  }
}

Ideas?

1

1 Answers

0
votes

If a field is requested, it should be returned with either a value matching the field's type or else null. To do otherwise would break the spec.

There is no way you can modify this behavior through a schema directive. A field definition directive can only change runtime behavior by modifying the field's resolver. However, by the time the resolver is called, the selection set has already been determined so it's too late to modify it. Returning null or throwing an error are pretty much the only two options.

You might be able to implement some kind of workaround through either the formatResponse option or a custom plugin. However, because this behavior would break the spec, there's no telling if it wouldn't cause issues with client libraries or other tools.