Skip to content

[RFC] GraphQL adaptators improvements #2243

@Weakky

Description

@Weakky

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 sometimes total)

If you agree with me, I see two ways of enhancing this:

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 🙌

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions