SliceMachine broken GraphQL tree

Hello there,

I got a message from Adam who has a problem with GraphQL on one of his next.js app.
Could you help him please?

Dear Support!

Could you check what is the issue with the graphql in our project?

https://koinly-marketing.prismic.io/graphql

It worked earlier today but now it is not working here and from my nextJs app too.

The error message mention two slices but I didn't make a change in them recently.

{

"message": "Schema does not pass validation. Violations:\n\nObject type 'BlogpostBodyVideo_sectionDefaultSlice' must define one or more fields.\n\nObject type 'PageBodyContact_detailsDefaultSlice' must define one or more fields."

}

I pushed that two slices to Prismic again from my local but it didn't help.

Thank you for your help.

Adam

Same issue, was working fine and all of a sudden it wasnt...

Hello, everyone :cherry_blossom:

I just broke prismic graphQL you can check https://oxylabs-sm.prismic.io/graphql

Long story short I have hardcoded slices, which is not updated frequently and ATM this was faster solution. Page looks good, everything works for me, but trying to use graphQL to build sitemap
i get this error { "message": "Schema does not pass validation. Violations:\n\nObject type 'EnterpriseBodyNav_headerDefaultSlice' must define one or more fields.\n\nObject type 'PpcBodySmall_headerDefaultSlice' must define one or more fields." }

Fast solution, I will add random fields to these slices. Long term solution SM should not let push empty slices or create UID for every slice under the hood maybe. I'm not pro here, so please correct me.

Anyway, big thanks for team for this awesome tool!

Hi Everyone,

I'm looking in to this. I'll get back to you once I know more.

Thanks.

1 Like

Hi Everyone, (@antoine.gilbert , @juskeviciusarn , @robinyo )

Is there anyway one of you can send me a copy of your project so I can recreate this on my side and find a fix?

Thanks.

Hello @Phil ,

Sorry, I can't send you our production copy.

Hello @Phil,

Is there is any news on this issue?

Hey @juskeviciusarn,

@hugo.villain investigated this last week and this is what he found:

After investigation, we realised that it comes from how keys are handled by the GraphQL schema generator of Prismic.

How it works in Prismic

1/ The custom type builder enforces a rule on keys: [a-z][-_0-9a-z]*$ , which matches strings like my-title and my_title . It filters keys that don't match this regular expression.
2/ It then transforms these keys into camelCase.
3/ These keys are then collected to generate a valid GraphQL schema.
4/ When a request is made to the API, before resolving, the keys are transformed back to snake case format

As is, there is no way to bypass the filtering as the last step of the field resolver cannot differentiate a field that has been transformed from a field that hasn't. It's a weird situation where keys that have been correctly cased don't pass the regular expression.

With the local builder

On the local builder side, we don't enforce any limitations except on special characters. To me, it's an important feature as what you see in your schema should be what you get in your code. Also, most front-end developers prefer working with camelCase or PascalCase as it's easier to access in code (does not require brackets nor quotes).

Problems & Solutions

Different problems arise when trying to fix the issue.

I though of enforcing a rule in the editor for people using GraphQL (at least orally) and disallow camelCase in profit of dash-case. But, although the payload of the GraphQL API would be valid, the generated mocks would not as they would still contain the keys with dashes. We could check with API endpoint is used in the sm.json file and transform the keys if necessary but it doesn't look like a solid fix.

Another way of fixing the issue would be to create a flag for all newly created projects, called "ENFORCE_CAMEL_CASE", that would be used by the GraphQL schema generator and by the GraphQL resolver to check if the name has to be transformed (and back) or not. SliceMachine users could be migrated to use this flag automatically.

His suggested workaround is to create a function to transform the API ID's to the correct case. Like this one:

function camelize(text, separator = '-') {
  let words = text.split(separator);
  let result = '';
​
  words.forEach((word, index) => {
    if (index === 0) {
      word = word.replace(/./, (letter) => letter.toLowerCase());
      result += word;
      return;
    }
    word = word.replace(/./, (letter) => letter.toUpperCase());
    result += word;
  });
  return result;
}
​
function transformObject(obj = {}) {
  return Object.entries(obj).reduce((acc, [key, content]) => ({
    ...acc,
    [camelize(key)]: content
  }), {})
}
​
function mocksToPascalCase(mocks) {
  return mocks.map(mock => ({
    ...mock,
    primary: transformObject(mock.primary),
    items: (mock.items || []).map(transformObject)
  }))
}

use it like this:
mocksToPascalCase(mocks)

So, everywhere you use mocks (eg. in your stories, instead of passing mocks you should pass the result of the function

"Super untested but that's what's fun" - His words not mine. :laughing:

So that's the current situation with the and The Team are continuing to discussing solutions for this issue.

Thanks.