Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolver incompatibility with Postgraphile top-level Connections #369

Open
ariroseonline opened this issue Apr 9, 2021 · 7 comments
Open
Labels
kind/bug A reported bug.

Comments

@ariroseonline
Copy link

ariroseonline commented Apr 9, 2021

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.

@galvakojis
Copy link

Hello, having a same problem, but not sure if this a middleware issue or postgraphile

@maticzav
Copy link
Owner

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.

@maticzav maticzav added the kind/bug A reported bug. label May 23, 2021
@galvakojis
Copy link

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

@Khauri
Copy link

Khauri commented Sep 24, 2021

I'm also having this issue. Has a workaround or any other insight been found?

@Khauri
Copy link

Khauri commented Sep 29, 2021

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.

@galvakojis
Copy link

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

@pschmidtudig
Copy link

pschmidtudig commented Jun 2, 2022

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);
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug A reported bug.
Projects
None yet
Development

No branches or pull requests

5 participants