Closed Simply007 closed 4 years ago
The current workaround is to create a dummy item for all content types with all the fields filled as it is in WordPress: https://github.com/gatsbyjs/gatsby/issues/5296
@Simply007 are we in a position to be able to resolve this issue now with the new schema customisation API?
https://github.com/gatsbyjs/gatsby/blob/master/docs/docs/schema-customization.md
Specifically the ability to opt-out of type inference and therefore specify custom types for fields:
It seems like this would allow the schema to properly match the Kentico Cloud JS SDK and will avoid the issue of missing fields when data is unavailable.
To be honest it feels like a source plugin based on a dynamic schema like Kentico Cloud should opt for Type Builders - https://www.gatsbyjs.org/docs/schema-customization/#gatsby-type-builders
This should allow types to be constructed from scratch. There are many types which should be defined once and shared, for example:
However, probably the worst thing for a consumer of the plugin is that all of these issues are so difficult to fix using the new schema customization as the original type definition produces so many unique types. Currently if we wanted to add a resolver to all Asset fields we would need to manually add a resolver to each unique Asset field by name, e.g.:
These are both Asset fields, from the same content type snippet on two different content models. However they result in two different types being created.
Also, on the topic of content type snippets. The schema customization API opens up some serious opportunities to make the schema more composable and usable when querying. For example, if we had two different types that use the same content type snippet there could be an interface defined to make sure these fields are shared:
interface SnippetMetadata {
metadata__page_title: String!
metadata__page_description: String!
metadata__page_keywords: String!
}
type KenticoCloudItemHomePage implements Node & SnippetMetadata {
metadata__page_title: String!
metadata__page_description: String!
metadata__page_keywords: String!
}
type KenticoCloudItemBlogPost implements Node & SnippetMetadata {
metadata__page_title: String!
metadata__page_description: String!
metadata__page_keywords: String!
}
Furthermore, fragments could then be used to make querying types for specific snippets even easier!
{
fragment SnippetMetadataFragment on SnippetMetadata {
metadata__page_title
metadata__page_description
metadata__page_keywords
}
allKenticoCloudItemHomePage {
edges {
node {
elements {
...SnippetMetadataFragment
}
}
}
}
allKenticoCloudItemBlogPost {
edges {
node {
elements {
...SnippetMetadataFragment
}
}
}
}
}
Note: I've simplified what a field is here, really they would need to share some other complex type such as TextField
with the appropriate name
, type
, value
properties.
I think the next major version (v7?) should be focused on re-architecting the type generation to use the new schema customisation API. The benefits to be gained are enormous, it will make the schema much more sane and predictable and should mean the plugin is subject to fewer bugs and mean consumers can get on with the important things... Like building awesome and fast websites! π
Sorry for the wall of text!
An update on my previous comment, I've put together a POC for the explicit type generation.
Currently this does the following:
system
property and also for the TextElement
field type.KontentItem
which allows all content items to be queried at the top level using allKontentItem
which could be a useful utility for sitemaps etc.In it's current state the schema displays all possible fields on a particular type, most are defined with basic scalar types as the Element
specific types are not yet defined.
Also I've not looked at any resolution of linked items or rich text yet.
Anyway, felt this could be a good reference point for this issue to be looked at.
Latest updates to my POC have added support for modular_content
fields via the @link
directive.
type KontentModularContentElement implements KontentElement @infer {
name: String!
type: String!
value: [KontentItem] @link(by: "system.codename")
}
This results in a field that handles null values, always has the KontentItem
interface as it's value type and can therefore be spread across to access type-specific fields:
query MyQuery {
allKontentItemAbout {
nodes {
elements {
sectionsSections {
value {
system {
type
}
... on KontentItemTwinColumnSection {
id
elements {
title {
value
}
}
}
}
}
}
}
}
}
{
"data": {
"allKontentItemAbout": {
"nodes": [
{
"elements": {
"sectionsSections": {
"value": null
}
}
},
{
"elements": {
"sectionsSections": {
"value": [
{
"system": {
"type": "twin_column_section"
},
"id": "97ff5c85-4f37-5666-8852-b54817934702",
"elements": {
"title": {
"value": "The Project"
}
}
},
{
"system": {
"type": "triple_column"
}
},
{
"system": {
"type": "partnership"
}
}
]
}
}
}
]
}
}
}
Update:
hey all - @makma and I are currently working on the schema definition for Kontent Gatsby Source plugin.
See the code in the schema-definition branch.
π π π Thanks @rshackleton! Your showcase was extremely valuable and mentioned implementation is applying most of the suggestions from your showcase!
Brief bug description
The issue is described in https://rshackleton.co.uk/articles/gotchas-and-workarounds-with-gatsby-and-kentico-cloud-part-1
Repro steps
Expected behavior
The query should return empty data without error.
GraphQL schema generator might help with implementation: https://github.com/Kentico/kentico-cloud-graphql-schema-generator
Additional context
Twitter feed: https://twitter.com/shackleberry112/status/1132245949491896320 @rshackleton's article with description how to implement the schema customization on the application https://rshackleton.co.uk/articles/learning-about-gatsby-schema-customisation-with-kontent-ai