-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Description
Hey there,
As of now, most GraphQL adaptators aren't taking full advantage of one of GraphQL's biggest benefit: being able to query nested fields in one request, as deep as the schema allow us to.
Instead, they're more or less imitating the way REST works, by making X request for X reference needed (although some great optimizations were already done in that regard https://marmelab.com/blog/2016/10/18/using-redux-saga-to-deduplicate-and-group-actions.html)
I think there are ways we could improve that, and I suggest we use this place as a central thread to discuss about what could be done.
Suggestion n°1
Include all scalar fields of linked types by default
As of now, we're only fetching ids from linked types, which forces us to use <ReferenceField />
on every linked type.
const linkedResource = introspectionResults.resources.find(
r => r.type.name === type.name
);
if (linkedResource) {
return { ...acc, [field.name]: { fields: { id: {} } } };
}
One quick-fix that could be done, is to automatically fetch all scalar fields of linked types:
const linkedResource = introspectionResults.resources.find(r => r.type.name === type.name);
if (linkedResource) {
// Fetch all linked resource scalar fields
const linkedScalarFields = linkedResource.type.fields
.filter(field => getFinalType(field.type).kind !== TypeKind.OBJECT)
.reduce((acc, field) => ({ ...acc, [field.name]: {} }), {});
return { ...acc, [field.name]: { fields: linkedScalarFields } };
}
This way, we're able to use <TextField source="linkedType.scalarField" />
, which already cover lots of cases and greatly improve the amount of request made.
I think the few more bytes that those additional fields will take on every requests are more than worth the amount of request that it will save.
Suggestion n°2
Make this overridable
After thinking about it, @fzaninotto, I don't think there's a need for a function to transform the introspectionResults
. The introspection query already fetches all the existing types (and their fields) anyway.
If I'm not mistaking, overriding the behavior described above is actually already possible and that's what you've done here, by overriding the query that fetches the Command
.
I think we could provide a simpler and more concise API to do that, for two reasons:
-
The query name and the params are not needed for what we're trying to achieve. The params will always have to be declared anyway, and it can become heavy when overriding
GET_LIST
actions (having filters, sorting and pagination as input). -
Users have to be careful about the aliases (
data
and sometimestotal
)
If you agree with me, I see two ways of enhancing this:
- By providing the same API GraphQL Bindings offers: a simple string.
const COMMAND_FIELDS = `{
id
reference
product { id name }
}`
- By providing the same API as
graphqlify
expects (more consistent, but heavier IMO)
That's all for now, tell me what you guys think 🙌