Skip to content

Instantly share code, notes, and snippets.

@the-vampiire
Last active March 20, 2020 05:06
Show Gist options
  • Select an option

  • Save the-vampiire/3d4875ef51c18c20fa3a53fd9307aa63 to your computer and use it in GitHub Desktop.

Select an option

Save the-vampiire/3d4875ef51c18c20fa3a53fd9307aa63 to your computer and use it in GitHub Desktop.
5 line Apollo Server GraphQL Type resolver efficiency proof of concept
const mapAttributes = (model, { fieldNodes }) => {
// get the fields of the Model (columns of the table)
const columns = new Set(Object.keys(model.rawAttributes));
const requested_attributes = fieldNodes[0].selectionSet.selections
.map(({ name: { value } }) => value);
// filter the attributes against the columns
return requested_attributes.filter(attribute => columns.has(attribute));
};
...
User: async (
_, // instance (not used in Type resolver)
{ username, ... }, // arguments
{ models: { User }, ... }, // context
info,
) => {
if (username) {
// before (entire row queried)
// return User.findOne({ where: { username } }); ...
// after (only requested columns queried)
return User.findOne({
where: { username },
attributes: mapAttributes(User, info),
});
} ...
}
...
@Maelstroms38
Copy link

Maelstroms38 commented Mar 19, 2020

Hey there, I ran into some issues when running this with a nested selection set i.e.

query {
  user {
    posts {
      id
      comments {
        title
        author {
          id
        }
      }
    }
  }
}

To help resolve this, I came up with the following edits:

const mapAttributes = (model, { fieldNodes }) => {
  // get the fields of the Model (columns of the table)
  const columns = new Set(Object.keys(model.rawAttributes));
  // get nested attributes for each selection set
  const nested_attributes = selectionSet =>
    (selectionSet &&
      selectionSet.selections &&
      selectionSet.selections.reduce(
        (acc, { name: { value }, selectionSet }) =>
          new Set([...acc, value, ...nested_attributes(selectionSet)]),
        new Set()
      )) ||
    [];
  const requested_attributes = nested_attributes(fieldNodes[0].selectionSet);
  // filter the attributes against the columns
  return [...requested_attributes].filter(attribute => columns.has(attribute));
};

Hope this helps!

@the-vampiire
Copy link
Author

nice man. thanks for the update. do you have a medium account? i can update the article and credit you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment