I started working with GraphQL Modules, and they introduce the concept of middlewares, in which you can apply at different levels.
I configured a middleware for my whole application like this to require authentication:
export const modularApp = createApplication({
    modules: [customerModule, premiumModule],
    middlewares: {
        "*": {
            "*": [authMiddleware],
        },
    },
});
export function authMiddleware({ root, args, context, info }, next) {
  if (context.authenticated) {
    throw new AuthenticationError("Unauthorized");
  }
  return next();
}
However there are a few queries and mutations that I'd like to bypass the authMiddleware, because they are public. I thought adding them on the module level would override the application middleware:
export default createModule({
  id: 'customer-module',
  dirname: __dirname,
  typeDefs,
  resolvers,
  middlewares: {
    'Query': {
      'somePublicOperation': [publicMiddleware],
    }
  },
});
export function publicMiddleware({ root, args, context, info }, next) {
  // bypass authMiddleware
  return next();
}
Both middlewares are executed instead, so I can't figure a solution for this issue.
I could add the authMiddleware individually to operations, but that's not very scalable as most operations require auth. Another idea is creating separate modules for public/protected operations, but I'm not sure what is the performance impact since both rely on the same types.