graphql-query-path
graphql-query-path copied to clipboard
Library to use field selection to mitigate the N+1 problem of GraphQL queries
graphql-query-path
A library that allows you to smartly execute database queries by looking at the field selection. This can mitigate the N+1 and even 1+1 problem of GraphQL queries.
This repo contains two projects:
- graphql-query-path that has two functions:
getPathsandgetPathsFromAST. They return a list of paths reflecting the graphql-query - graphql-query-path-contains the same as above and extends
Arraywithcontains(glob: string): booleanmethod that you can use to do glob matching. This one is ~17k bigger because of a dependency onpicomatch.
What is it
Given the following query
query {
user {
name
posts {
title
content
}
}
}
the getPaths(info) returns the following array
[
'/user',
'/user/name',
'/user/posts/',
'/user/posts/title',
'/user/posts/content',
];
This array can give the information you need to execute a querybuilder or call other APIs in an efficient way.
Usage
Install the package
npm i graphql-query-path
Use it in your graphql-resolver:
import { getPaths } from 'graphql-query-paths';
// or
// const { getPaths } = require('graphql-query-paths');
const resolvers = {
user(args, context, info) {
// for example this query comes in
// query: {
// user {
// name
// posts {
// title
// content
// }
// }
// }
const paths = getPaths(info);
// paths: [
// '/user',
// '/user/name',
// '/user/posts/',
// '/user/posts/title',
// '/user/posts/content'
// ]
if (paths.find((p) => p.indexOf('/user/posts/') > -1)) {
db.getUsersWithPosts();
} else {
db.getUsers();
}
},
};
Use the extended version to match glob pattern with contains from
graphql-query-paths-contains. This includes picomatch but increases the lib
size by ~17k.
npm i graphql-query-paths-contains
import { getPaths } from 'graphql-query-paths-contains';
// or
// const { getPaths } = require('graphql-query-paths-contains');
const resolvers = {
user(args, context, info) {
if (getPaths(info).contains("/users/posts/"))) {
db.getUsersWithPosts();
} else {
db.getUsers();
}
},
};
Interface docs
Library graphql-query-paths
| function/argument | type | description |
|---|---|---|
| getPathsFromAST(ast) | string[][] |
Returns a list of subqueries with paths reflected in the sub query per subquery |
| ast | DocumentNode link |
The DocumentNode from import { parse } from 'graphql' |
| getPaths(info) | string[] |
Returns a list of paths reflected in the query |
| info | GraphQLResolveInfo link |
The last argument in a resolver |
Library graphql-query-paths-contains extends the library above with a
contains function
| function/argument | type | description |
|---|---|---|
| Array.prototype.contains(glob) | boolean |
Extends Array with contains function. To know if a result contains a path you can execute getPaths(info).contains("/user/**"). This returns a boolean |
| glob | string |
a string representing a glob to filter the array with |
Potential features
- [ ] Create a
pathContains(info, pattern)function that can lazily find instead of extracting all paths firsts
Author
Albert Groothedde
Contributing
Contributions, issues and feature requests are welcome!
Feel free to check issues page.
Show your support
Give a ⭐️ if this project helped you!
This README was generated by readme-md-generator