Last active
June 26, 2019 10:15
-
-
Save fenos/fc4672d32f179b27aec8b92a819ee8ba to your computer and use it in GitHub Desktop.
Dataloader and GraphQL passing arguments
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// GraphQL query that i'm trying to resolve with Dataloader but i can't find a way to pass argument to the | |
// loader function. | |
// The following GraphQL query should invoke the following DB round trips | |
// 1 - Posts * | |
// 2 - Tags limit 10 where post_id = ? | |
// 3 - Tags limit 20 where post_id = ? | |
query limitTagsOfThePost { | |
posts { | |
name | |
tags(limit: 10) { | |
name | |
} | |
tags(limit: 20) { | |
name | |
} | |
} | |
} | |
// GraphQL Types: Tag and Posts | |
const TagType = new GraphQLObjectType({ | |
name: 'Tag', | |
fields: () => { | |
return { | |
id: { | |
type: new GraphQLNonNull(GraphQLID) | |
}, | |
name: { | |
type: new GraphQLNonNull(GraphQLString) | |
} | |
}; | |
} | |
}); | |
const PostType = new GraphQLObjectType({ | |
name: 'Post', | |
fields: () => { | |
return { | |
id: { | |
type: new GraphQLNonNull(GraphQLID) | |
}, | |
name: { | |
type: GraphQLString | |
}, | |
tags: { | |
type: new GraphQLList(TagType), | |
resolve: (post, {limit}) => { | |
// Here I have the LIMIT argument which allows me | |
// to limit the tags of the posts. But i can't understand | |
// which pattern i should use to allow the argument to be injected | |
// into the getPostTagsUsingPostId loader function. | |
return TagByPostIdLoader.load(post.id); | |
} | |
} | |
}; | |
} | |
}); | |
const TagByPostIdLoader = new DataLoader(getPostTagsUsingPostId); | |
// Loader | |
// Here i want to have the args passed from the GraphQL query | |
// maybe as a second argument? so that i can add limit to the tags. | |
const getPostTagsUsingPostId = (postIds) => { | |
return Post | |
.collection(postIds.map((id) => { | |
return { | |
id | |
}; | |
})) | |
.load('tags') | |
.call('toJSON') | |
.then((collection) => { | |
// Bookshelf 0.10.0 uses Bluebird ^2.9.4. | |
// Support for .mapSeries has been added in Bluebird v3. | |
return collection.map((post) => { | |
return post.tags; | |
}); | |
}); | |
}; |
I am also having this issue, anyone find a solution?
Me too. Anyone?
for someone who still needs something look alike to achieve this:
import cloneDeep from 'lodash/cloneDeep';
import isObjectLike from 'lodash/isObjectLike';
const options = {
cacheKeyFn: (key) => (isObjectLike(key)) ? JSON.stringify(cloneDeep(key)) : key,
};
const mergeKeys = arr => ({
keys: _.map(arr, 'key'),
args: _.merge(...(_.map(arr, 'arguments')))
});
const loader = async (data, { User }) => { // User is the model
const { keys, args } = mergeKeys(data);
const pagination = args.pagination ? args.pagination : {};
console.log(pagination)
const users = await User.findAll({
raw: true,
where: {
id: {
$in: keys,
}
},
...pagination,
});
console.log(users);
const groupUsers = _.groupBy(users, 'id');
return keys.map(key => groupUsers[key]);
}
new DataLoader((keys) => loader(keys, models), options)
Not working for me
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Did you ever find a solution @fenos ?
I'm facing a similar problem, I can't really find anything.