Support for multiple middlewares
Faisal-Manzer opened this issue · comments
Faisal Manzer commented
When tried to use multiple middle-wares with a query it failed with the errors below.
/Users/user/Desktop/example/node_modules/graphql-middleware/dist/validation.js:20
throw new MiddlewareError(`Expected ${type}.${field} to be a function but found ` +
^
MiddlewareError: Expected Query.secured to be a function but found object
at /Users/user/Desktop/example/node_modules/graphql-middleware/dist/validation.js:20:27
at Array.forEach (<anonymous>)
at /Users/user/Desktop/example/node_modules/graphql-middleware/dist/validation.js:15:43
at Array.forEach (<anonymous>)
at Object.validateMiddleware (/Users/user/Desktop/example/node_modules/graphql-middleware/dist/validation.js:9:29)
at addMiddlewareToSchema (/Users/user/Desktop/example/node_modules/graphql-middleware/dist/middleware.js:19:42)
at normalisedMiddlewares.reduceRight.schema.schema (/Users/user/Desktop/example/node_modules/graphql-middleware/dist/middleware.js:52:87)
at Array.reduceRight (<anonymous>)
at applyMiddlewareWithOptions (/Users/user/Desktop/example/node_modules/graphql-middleware/dist/middleware.js:51:79)
at applyMiddleware (/Users/user/Desktop/example/node_modules/graphql-middleware/dist/middleware.js:78:12)
const {
GraphQLServer
} = require('graphql-yoga')
const typeDefs = `
type Query {
open: String!
secured: String!
me: Me!
}
type Me {
name: String!
surname: String!
age: Int!
}
`
const code = 'supersecret'
const isLoggedIn = async (resolve, parent, args, ctx, info) => {
// Include your agent code as Authorization: <token> header.
const permit = ctx.request.get('Authorization') === code
if (!permit) {
throw new Error(`Not authorised!`)
}
return resolve()
}
+ const log = async (resolve, parent, args, ctx, info) => {
+ console.log('Aqwertyuiop');
+ return resolve()
+ }
const resolvers = {
Query: {
open: () => `Open data, everyone's welcome!`,
secured: () => `Personal diary - this is for my eyes only!`,
me: () => ({}),
},
Me: {
name: () => 'Ben',
surname: () => 'Cool',
age: () => 18,
},
}
// Middleware - Permissions
const permissions = {
Query: {
+ secured: [log, isLoggedIn],
- secured: isLoggedIn,
},
Me: isLoggedIn,
}
// Server
const server = new GraphQLServer({
typeDefs,
resolvers,
context: req => ({
...req
}),
middlewares: [permissions],
})
server.start(() => console.log('Server is running on http://localhost:4000'))
Is there any support for multiple middle-wares?
There can be an utility function or in-build support for multiple middleware.
Faisal Manzer commented
This can be easily solved by an utility function
const combineMiddlewares = (...middlewares) => async (resolve, parent, args, context, info) => {
if (middlewares.length === 0) return resolve(parent, args, context, info);
const mCopy = [...middlewares];
const middleware = mCopy.pop();
const next = (mParent = parent, mArgs = args, mContext = context, mInfo = info) => combineMiddlewares(...mCopy)(resolve, mParent, mArgs, mContext, mInfo);
return await middleware(next, parent, args, context, info);
}
So, now it works
const permissions = {
Query: {
secured: combineMiddlewares(log, isLoggedIn),
secured: isLoggedIn,
},
Me: isLoggedIn,
}
Can we have some builtin support rather than using workarounds?
Matic Zavadlal commented
There's a built in support. You may add multiple middlewares and graphql middleware should handle them. That's why there's a list parameter for middlewares
not a singleton.
Faisal Manzer commented
Can you give some code example?