brielov
brielov

Reputation: 1947

ApolloServer not firing custom directives

I'm trying to write some authentication logic based on apollo server documentation but it doesn't seem to be firing. Here's my code:

// schemas/auth-schema.js
import gql from 'graphql-tag';

export const typeDefs = gql`
  directive @auth(requires: Role = ADMIN) on OBJECT | FIELD_DEFINITION
`;
// directives/auth-directive.js
import { SchemaDirectiveVisitor } from 'apollo-server';

export default class AuthDirective extends SchemaDirectiveVisitor {
  visitObject(type) {
    console.log('HERE');
  }
  visitSchema() {
    console.log('HERE');
  }
  visitFieldDefinition() {
    console.log('HERE');
  }
}
// schemas/post-schema.js
import gql from 'graphql-tag';
import { Post } from '../models';

export const typeDefs = gql`
  type Post @auth(requires: ADMIN) {
    body: String!
    description: String!
    id: ID!
    image: String!
    publishedAt: DateTime
    readingTime: Int!
    slug: String!
    title: String!
  }

  input PostInput {
    body: String!
    description: String!
    image: String!
    publishedAt: DateTime
    title: String!
  }

  extend type Query {
    posts: [Post!]! @auth(requires: ADMIN)
  }

  extend type Mutation {
    addPost(input: PostInput!): Post! @auth(requires: ADMIN)
  }
`;

export const resolvers = {
  Query: {
    posts: () => Post.find({}),
  },
  Mutation: {
    addPost: (_, { input }) => Post.create(input),
  },
};

// index.js

import { ApolloServer } from 'apollo-server';
import mongoose from 'mongoose';
import AuthDirective from './directives/auth-directive';
import * as config from './config';

mongoose.set('useNewUrlParser', true);
mongoose.set('useCreateIndex', true);
mongoose.set('debug', config.env !== 'production');

const server = new ApolloServer({
  modules: [
    require('./schema/auth-schema'),
    require('./schema/date-schema'),
    require('./schema/post-schema'),
    require('./schema/role-schema'),
    require('./schema/user-schema'),
  ],
  schemaDirectives: {
    auth: AuthDirective,
  },
});

async function boot() {
  await mongoose.connect(config.mongo.url);
  await server.listen(config.http.port);
  console.log(`server listening on port ${config.http.port}`);
}

async function shutdown() {
  await server.stop();
  await mongoose.disconnect();
  console.log(`server shutted down`);
  process.exit(0);
}

process.on('SIGINT', shutdown);
process.on('SIGTERM', shutdown);

boot();

So, I've tried putting the @auth directive in every possible case and nothing is being fired.

type Post @auth(requires: ADMIN) { ... } // not firing

type Query {
  posts: [Post!]! @auth(requires: ADMIN) // not firing
}

This is what AdminDirective is evaluated from the console: enter image description here

What am I doing wrong?

Upvotes: 2

Views: 1297

Answers (1)

Daniel Rearden
Daniel Rearden

Reputation: 84657

So, looking at the code for apollo-server, when you use the modules option, internally your schema is built using buildServiceDefinition. While this function does merge directives from all the modules, it's not passed your schemaDirectives object and does not apply it.

In other words, this looks like a bug with apollo-server itself. You can file an issue, and in the meantime, just use the typeDefs and resolvers options, combining the necessary files yourself.

Upvotes: 2

Related Questions