graphql-middleware
graphql-middleware copied to clipboard
Resolver incompatibility with Postgraphile top-level Connections
Hi!
I am trying to use the awesome graphql-shield
library with Postgraphile
. In order to do so, I must use graphql-middleware
. After thoroughly narrowing in on the problem, I've arrived at the following base case:
Let's say we have an item
table in Postgres. Postgraphile generates a schema
automatically, with AllItems
and itemById
fields. We send the schema through
applyMiddleware(schema, async (resolve, root, args, context, info) => {
const resultingSchema = await resolve(root, args, context, info);
return resultingSchema;
};)`
which is then returned to Postgraphile plugin system, which becomes the finalized schema.
I then execute a query like so:
query MyQuery {
allItems {
nodes {
name
}
}
itemByID(id: 5) {
name
}
}
The itemByID
will execute properly and return the right data, but allItems
does not:
"stack": "TypeError: Cannot read property 'map' of undefined\n
at resolve ([redacted]/node_modules/graphile-build-pg/src/plugins/PgTablesPlugin.js:501:44)\n
at ([redacted]/node_modules/graphql-middleware/src/applicator.ts:35:9\n
[redacted irrelevant calls from application code/router]
It seems to be a problem with Connection type fields on the top level, which include nodes
and edges
arrays of objects (you can see nodes being queried in the allItems field). I did some experimentation, and it can even handle relational nested Connections inside itemByID
if I declared them (let's say relatedItems
for example). But it appears to be improperly handling and traversing Connections specifically when they're at the top level of the query, like allItems
.
To simplify the Connections format, I even tried Postgraphile with the simple connections option instead of Relay-format connections. That gets rid of the nodes
and edges
array fields on Connections and so just returns an array immediately from allItems
. But the resolving/traversal still remained a problem: They were now actually properly returning an array of objects but there were values of null
for every object field in the object array, meaning the leaf scalar values didn't appear to be resolved properly. So exchanging one problem for another in resolution.
After looking closely, the problem seems to lie somewhere in the applicator
's generateResolverFromSchemaAndMiddleware
properly traversing the resolvers or when running the addResolversToSchema
that generates a new schema for output.
It just seems like in the current state, that graphql-middleware
is not compatible with Postgraphile's generated schemas as inputs.
Any pointers, clues, or solutions you can think of? We are so excited to use the graphql-shield library, but this schema translation step seems to be broken.
Hello, having a same problem, but not sure if this a middleware issue or postgraphile
Hi all! 👋
It would be great if you could compose a small reproduction CodeSandbox or something similar? I think this could be an inherent issue with how graphql-middleware
was initially written, but I have an idea about how we could solve it. Having a reproduction could really speed up the process.
Hi all! 👋
It would be great if you could compose a small reproduction CodeSandbox or something similar? I think this could be an inherent issue with how
graphql-middleware
was initially written, but I have an idea about how we could solve it. Having a reproduction could really speed up the process.
This was first CodeSandbox , spend almost two hours, looks like that I was able to recreate issue. .https://codesandbox.io/s/nice-hypatia-y0dro?file=/app.js https://y0dro.sse.codesandbox.io/graphiql when I don't use shield all players are returned when I use, I get an issue
I'm also having this issue. Has a workaround or any other insight been found?
It seems that the problem may be in part coming from @graphql-utils/schema
's addResolversToSchema
function as used by graphql-middleware here: https://github.com/maticzav/graphql-middleware/blob/master/src/middleware.ts#L42
I created a simple plugin to test this:
const {makeExtendSchemaPlugin, makePluginByCombiningPlugins, gql} = require('graphile-utils');
const {addResolversToSchema} = require('@graphql-tools/schema');
const testPlugin = (builder) => {
builder.hook('finalize', schema => addResolversToSchema({schema, resolvers: {Mutation: {test: () => true}}}));
};
module.exports = makePluginByCombiningPlugins(
makeExtendSchemaPlugin({typeDefs: gql`extend type Mutation { test: Boolean }`}),
testPlugin,
);
And it results in the same error.
I'm also having this issue. Has a workaround or any other insight been found?
I lost hope to get any attention to this, so instead using this library went to solution similar to this
I found a workaround for this (somewhat by accident). If you add a step to first wrap the schema using @graphql-tools/wrap, you can apply the middleware as usual and graphql-shield works as expected.
I've tested this with postgraphile running on both Apollo Server (schema only) and Express (as library)
Example plugin:
const { makeProcessSchemaPlugin } = require("graphile-utils");
const permissions = require('../auth/permissions')
const { wrapSchema } = require('@graphql-tools/wrap')
const { applyMiddleware } = require('graphql-middleware')
module.exports = makeProcessSchemaPlugin(schema => {
const wrappedSchema = wrapSchema({
schema: schema,
transforms: []
});
return applyMiddleware(wrappedSchema, permissions);
});