As requested by @DMehaffy , I’m copy-pasting my github issue related to this discussion here:
-----------------------------------------------------------8<-----------------------------------------------------------
Bug report
Describe the bug
Because of id
and attributes
split in API schema the GraphQL cache can’t be updated and raise a warning in the browser console (among obvious cache handling issue).
The warning message from the console is:
invariant.ts?6cf4:42 Cache data may be lost when replacing the attributes field of a ExampleEntity object.
To address this problem (which is not a bug in Apollo Client), either ensure all objects of type Example have an ID or a custom merge function, or define a custom merge function for the ExampleEntity.attributes field, so InMemoryCache can safely merge these objects:
existing: {"__typename":"Example","createdAt":"2021-12-25T23:43:56.648Z","firstName":"John","lastName":"Do","message":"I'm asleep","status":"NEW","dueDate":null,"referer":"https://example.com","contactDetails":[],"user":{"__typename":"UsersPermissionsUserEntityResponse","data":null}}
incoming: {"__typename":"Example","dueDate":null,"firstName":"John","lastName":"Do","message":"I'm asleep","referer":"https://example.com","ipAddress":"12.34.56.78","createdAt":"2021-12-25T23:43:56.648Z","updatedAt":"2021-12-25T23:43:56.648Z","contactDetails":[],"communications":[]}
For more information about these options, please refer to the documentation:
* Ensuring entity objects have IDs: https://go.apollo.dev/c/generating-unique-identifiers
* Defining custom merge functions: https://go.apollo.dev/c/merging-non-normalized-objects
This is because the GraphQL schema is the following:
example(id: ID): ExampleEntityResponse
type ExampleEntityResponse {
data: ExampleEntity
}
id: ID
and
data: ExampleEntity
type ExampleEntity {
id: ID
attributes: Example
}
Steps to reproduce the behavior
- Using GraphQL API, request the same asset in a query and in the result of a mutation (for example)
- See warning message in the browser console
Expected behavior
The id
and attributes
split in the GraphQL API schema is incomprehensible for me. I can’t understand why there are not in the same object (like Apollo Client
is obviously expecting to find it). In addition, I also can’t understand why we need to wrap everything in a data
object while fetching a single asset. I guess there is strong reasons for such things, but I can’t actually believe them
IMHO, the expected schema should be like this:
example(id: ID!): Example
type Example {
id: ID!
createdAt: DateTime!
updatedAt: DateTime!
// other fields...
}
Screenshots
N/A
Code snippets
Regardless the GraphQL cache issue, I’m currently forced to write such code in every query/mutation (and I really hate it ):
function Example({ id, attributes }) {
Object.assign(this, { id, ...attributes });
}
this.$apollo
.query({ query: examplesQuery, variables: { ids: this.ids } })
.then(({ data: { examples: { data } } }) => {
const examples = data.map(e => new Example(e));
// finally some useful code
}
Strapi v3 use by far more “dev friendly” in this respect (no useless data
wrapper for single asset, no incomprehensible id
and attributes
split).
System
- Node.js version: v16.13.1
- NPM version: v8.1.2
- Strapi version: v4.0.5
- Database: MariaDB
- Operating system: Archlinux
-----------------------------------------------------------8<-----------------------------------------------------------