graphql-fields
Turns GraphQLResolveInfo into a map of the requested fields. Flattens all fragments and duplicated fields into a neat object to easily see which fields were requested at any level. Takes into account any @include
or @skip
directives, excluding fields/fragments which are @include(if: $false)
or @skip(if: $true)
.
Usage
Schema Type definition
const graphqlFields = ;const graphql = const UserType = name: 'User' fields: profile: type: name: 'Profile' fields: firstName: type: graphqlGraphQLString lastName: type: graphqlGraphQLString middleName: type: graphqlGraphQLString nickName: type: graphqlGraphQLString maidenName: type: graphqlGraphQLString email: type: graphqlGraphQLString id: type: graphqlGraphQLID ); moduleexports = query: name: 'Query' Object
Query
{ user { ...A profile { ...B firstName } }} fragment A on User { ...C id, profile { lastName }} Fragment B on Profile { firstName nickName @skip(if: true)} Fragment C on User { email, profile { middleName maidenName @include(if: false) }}
will log
subfields arguments
To enable subfields arguments parsing, you'll have to provide an option object to the function. This feature is disable by default.
const graphqlFields = ;const fieldsWithSubFieldsArgs = ;
For each subfield w/ arguments, a __arguments
property will be created.
It will be an array with the following format:
arg1Name: kind: ARG1_KIND value: ARG1_VALUE arg2Name: kind: ARG2_KIND value: ARG2_VALUE
The kind property is here to help differentiate value cast to strings by javascript clients, such as enum values.
Exclude specific fields
Most of the time we don't need __typename
to be sent to backend/rest api, we can exclude __typename
using this:
const graphqlFields = ;const fieldsWithoutTypeName = ;
Why
An underlying REST api may only return fields based on query params.
{ user { profile { firstName }, id }}
should request /api/user?fields=profile,id
while
{ user { email }}
should request /api/user?fields=email
Implement your resolve method like so:
resolve(root, args, context, info) {
const topLevelFields = Object.keys(graphqlFields(info));
return fetch(`/api/user?fields=${topLevelFields.join(',')}`);
}
Tests
npm test