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

GraphQL support for Gridsome (and maybe Gatsby) #487

Closed
wbrowar opened this issue Oct 15, 2019 · 12 comments
Closed

GraphQL support for Gridsome (and maybe Gatsby) #487

wbrowar opened this issue Oct 15, 2019 · 12 comments
Labels
need info Need more information on the issue

Comments

@wbrowar
Copy link

wbrowar commented Oct 15, 2019

Performing a GraphQL query in Gridsome returns a __typename error indicating that the schema might not be defined in a way that Gridsome can accept.

This query in Gridsome’s GraphQL explorer:

  query {
    craft {
      seomatic {
        metaTitleContainer
      }
    }
  }

Results in this error:

{
  "errors": [
    {
      "message": "__typename did not match an object type: seomatic",
      "stringified": "__typename did not match an object type: seomatic\n\nGraphQL request:3:5\n2 |   craft {\n3 |     seomatic {\n  |     ^\n4 |       metaTitleContainer"
    }
  ],
  "data": {
    "craft": {
      "seomatic": null
    }
  }
}

One thing to note here is that when Craft is defining their interfaces and the types of arguments that can be passed in to a query, some types are defined within square brackets (perhaps this indicates they are looking for an array?). For example, looking at the schema for an entries() query in GraphQL Playground’s DOCS tab, it looks like this:

entries(
  id: [Int]
  uid: [String]
  status: [String]
  archived: Boolean
  ...etc...
): [craft_EntryInterface]

The schema for seomatic() looks like this:

seomatic(
  uri: String
  siteId: Int
  asArray: Boolean
): craft_SeomaticInterface

Note: the craft_ prefix is just the type prefix used by Gridsome.

@khalwat
Copy link
Collaborator

khalwat commented Oct 15, 2019

At this point, I'm not sure if this is an issue with SEOmatic, an issue with Gridsome, or an issue with the GraphQL implement in Craft CMS.

@dbrookes
Copy link

I'm seeing the same thing with Gatsby, seomatic is in the schema but errors when running the query:

Screenshot 2019-10-19 at 09 34 08

  "errors": [
    {
      "message": "__typename did not match an object type: seomatic",
      "locations": [
        {
          "line": 3,
          "column": 5
        }
      ],
      "path": [
        "craft",
        "seomatic"
      ],
      "stack": [
        "Error: __typename did not match an object type: seomatic",
        "    at new CombinedError (/Users/dbrookes/Sites/site/homepage/node_modules/graphql-tools/dist/stitching/errors.js:83:28)",
        "    at Object.checkResultAndHandleErrors (/Users/dbrookes/Sites/site/homepage/node_modules/graphql-tools/dist/stitching/errors.js:101:15)",
        "    at CheckResultAndHandleErrors.transformResult (/Users/dbrookes/Sites/site/homepage/node_modules/graphql-tools/dist/transforms/CheckResultAndHandleErrors.js:10:25)",
        "    at /Users/dbrookes/Sites/site/homepage/node_modules/graphql-tools/dist/transforms/transforms.js:19:54",
        "    at Array.reduce (<anonymous>)",
        "    at applyResultTransforms (/Users/dbrookes/Sites/site/homepage/node_modules/graphql-tools/dist/transforms/transforms.js:18:23)",
        "    at /Users/dbrookes/Sites/site/homepage/node_modules/graphql-tools/dist/stitching/delegateToSchema.js:102:50",
        "    at step (/Users/dbrookes/Sites/site/homepage/node_modules/graphql-tools/dist/stitching/delegateToSchema.js:40:23)",
        "    at Object.next (/Users/dbrookes/Sites/site/homepage/node_modules/graphql-tools/dist/stitching/delegateToSchema.js:21:53)",
        "    at fulfilled (/Users/dbrookes/Sites/site/homepage/node_modules/graphql-tools/dist/stitching/delegateToSchema.js:12:58)",
        "    at process._tickCallback (internal/process/next_tick.js:68:7)"
      ]
    }
  ],

@rjgux
Copy link

rjgux commented Oct 22, 2019

Having the same issue as #487 (comment) in Gatsby

@khalwat khalwat added the need info Need more information on the issue label Oct 22, 2019
@dangayle
Copy link

There's a fix for this upstream, needs to be implemented by plugin developers: craftcms/cms#5067

@khalwat
Copy link
Collaborator

khalwat commented Oct 23, 2019

This is a different issue @dangayle

So SEOmatic (and Retour) both register Interfaces -- which define generators that return objects for GraphQL to use.

The issue is here:

https://github.com/craftcms/cms/blob/develop/src/services/Gql.php#L232

            // Create a pre-built schema if that's what they want.
            $interfaces = [
                EntryInterface::class,
                MatrixBlockInterface::class,
                AssetInterface::class,
                UserInterface::class,
                GlobalSetInterface::class,
                ElementInterface::class,
                CategoryInterface::class,
                TagInterface::class,
            ];
            foreach ($interfaces as $interfaceClass) {
                if (!is_subclass_of($interfaceClass, InterfaceType::class)) {
                    throw new GqlException('Incorrectly defined interface ' . $interfaceClass);
                }
                /** @var GeneratorInterface $typeGeneratorClass */
                $typeGeneratorClass = $interfaceClass::getTypeGenerator();
                foreach ($typeGeneratorClass::generateTypes() as $type) {
                    $schemaConfig['types'][] = $type;
                }
            }

Craft iterates through a hard-coded list of Interfaces, and generates the the types for them... but since plugins are not given a chance to be added to said hard-coded list, they fail.

This is a "soft error" in the GraphQL implementation in Craft, but the Apollo layer added via Gatsby and Gridsome do additional type checking to ensure that the returned data matches a registered type:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var graphql_1 = require("graphql");
function resolveFromParentTypename(parent, schema) {
    var parentTypename = parent['__typename'];
    if (!parentTypename) {
        throw new Error('Did not fetch typename for object, unable to resolve interface.');
    }
    var resolvedType = schema.getType(parentTypename);
    if (!(resolvedType instanceof graphql_1.GraphQLObjectType)) {
        throw new Error('__typename did not match an object type: ' + parentTypename + ' -- ' + JSON.stringify(schema));
    }
    return resolvedType;
}
exports.default = resolveFromParentTypename;
//# sourceMappingURL=resolveFromParentTypename.js.map

...which fails, throwing an error.

I manually added my SeomaticInterface to the hard-coded list above, and everything worked peachy:

Screen Shot 2019-10-23 at 1 28 49 AM

Ref: craftcms/cms#5149

@dangayle
Copy link

@khalwat Isn't that what Andris mentions here?

craftcms/cms#5067 (comment)

@khalwat
Copy link
Collaborator

khalwat commented Oct 23, 2019

Nope, it's not @dangayle

@dangayle
Copy link

ok, my apologies for misunderstanding the issue

@khalwat
Copy link
Collaborator

khalwat commented Oct 23, 2019

No biggy. They look similar, but the underlying issue is a different one.

@andris-sevcenko
Copy link
Collaborator

This will be fixed in the next Craft release. Thanks for doing the legwork!

@khalwat
Copy link
Collaborator

khalwat commented Oct 23, 2019

Andris fixed this in craftcms/cms@4381b1c

I'll leave this open until the fixed version of Craft is released.

@khalwat
Copy link
Collaborator

khalwat commented Oct 23, 2019

This was fixed in Craft CMS 3.3.13, released today -> https://github.com/craftcms/cms/blob/develop/CHANGELOG-v3.md#3313---2019-10-23

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
need info Need more information on the issue
Projects
None yet
Development

No branches or pull requests

6 participants