graphile / graphile-engine

Monorepo home of graphile-build, graphile-build-pg, graphile-utils, postgraphile-core and graphql-parse-resolve-info. Build a high-performance easily-extensible GraphQL schema by combining plugins!
https://www.graphile.org/
762 stars 129 forks source link

graphql-parse-resolve-info scalar fields #809

Closed mdecurtins closed 2 years ago

mdecurtins commented 2 years ago

I use graphql-parse-resolve-info to provide a utility function, findInSelectionSet that recursively walks through the parsed resolve info and allows the resolver to find matches in the query selection set based on filters that apply either to the field name or to the field return type:

type SelectionSetMatch = {
  fieldName: string
  fieldType: string
  fieldArgs: Record<string, unknown>
}

type SelectionSetFilter = {
  fieldnameContains?: string
  fieldTypenameContains?: string
  // etc.
}

function findInSelectionSet( 
  parsedInfo: ReturnType<typeof parseResolveInfo>, 
  filter: SelectionSetFilter 
): Array<SelectionSetMatch> {
  // ...
}

My question is, is there a way to capture the field type for scalar fields? Currently, parseResolveInfo provides alias, name, args, and fieldsByTypename with an empty object ({}) for leaf nodes, but it doesn't look like we can tell whether the field is String, Int, Boolean, etc.

I can always just provide a value like 'SCALAR' for the fieldType property of my SelectionSetMatch when fieldsByTypename is empty, but it would be nice if I could actually capture the real scalar type.

Thanks very much!

benjie commented 2 years ago

Hey @mdecurtins; you can use the type name and the field name (name, not alias) in combination with the schema that's also on resolveInfo to determine the type from the schema; something like this:

const { getNamedType, isLeafType } = require('graphql');

const { schema } = resolveInfo;
const type = schema.getType(typeName);
const fields = type.getFields();
const fieldType = fields[fieldName].type;

// If you want to unwrap all the lists/non-nulls you can do:
const namedType = getNamedType(fieldType);

// If you want to determine if it's a leaf type:
const leaf = isLeafType(fieldType);

I don't think it would be wise for us to add this extra redundant data to graphql-parse-resolve-info because it would take longer to generate, impacting performance.

benjie commented 2 years ago

[semi-automated message] Thanks for your question; hopefully we're well on the way to helping you solve your issue. This doesn't currently seem to be a bug in the library so I'm going to close the issue, but please feel free to keep requesting help below and if it does turn out to be a bug we can definitely re-open it 👍

You can also ask for help in the #help-and-support channel in our Discord chat.