[RFC] GraphQL adaptators improvements
See original GitHub issueHey 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 🙌
Issue Analytics
- State:
- Created 5 years ago
- Reactions:5
- Comments:20 (20 by maintainers)
You should’ve seen my smile reading those sweet words 😂
This is fine for me. Your way of doing it is more consistent as you’re planning to remove the
override
option. Everything will have to be done by decorating the provider, offering more freedom. I’ll be able to use my cumbersome data structure anyway to avoid those ugly if statements 😄Exactly ! Let me recap everything:
override
option fromra-data-graphql
schema
into theintrospectionResults
(other usecases might be found in the future)I might find some time to send a few PR’s 🎉
Ok, I think I get what you’re doing now. Basically, you want a way to override a query without having to write the
query
boilerplate with parameters, etc.I think the
overrideQueriesByFragment
is cumbersome to use though. Taking your repository product as an example, I suggest doing something like the following:Besides, I assume the only thing we have to do on our side is to include the full schema in the
introspectionResults
so that you can validate fragments, etc. Right? We may then steal your code for our own providers 😛