https://github.com/alber70g/graphql-query-path
Library to use field selection to mitigate the N+1 problem of GraphQL queries
https://github.com/alber70g/graphql-query-path
Last synced: 7 months ago
JSON representation
Library to use field selection to mitigate the N+1 problem of GraphQL queries
- Host: GitHub
- URL: https://github.com/alber70g/graphql-query-path
- Owner: alber70g
- License: other
- Created: 2019-07-31T21:03:24.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2023-01-04T05:59:57.000Z (about 3 years ago)
- Last Synced: 2025-06-14T04:06:02.806Z (7 months ago)
- Language: TypeScript
- Size: 1.99 MB
- Stars: 16
- Watchers: 2
- Forks: 0
- Open Issues: 24
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-list - graphql-query-path
README
# 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: `getPaths` and
`getPathsFromAST`. They return a list of paths reflecting the graphql-query
- **graphql-query-path-contains** the same as above and extends `Array` with
`contains(glob: string): boolean` method that you can use to do glob matching.
This one is ~17k bigger because of a dependency on `picomatch`.
## What is it
Given the following query
```graphql
query {
user {
name
posts {
title
content
}
}
}
```
the `getPaths(info)` returns the following array
```js
[
'/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
```sh
npm i graphql-query-path
```
Use it in your graphql-resolver:
```js
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.
```sh
npm i graphql-query-paths-contains
```
```js
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](https://graphql.org/graphql-js/language/#parse) | The DocumentNode from `import { parse } from 'graphql'` |
| **getPaths(info)** | `string[]` | Returns a list of paths reflected in the query |
| info | `GraphQLResolveInfo` [link](https://graphql.org/graphql-js/type/#graphqlobjecttype) | 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**
- Twitter: [@alber70g](https://twitter.com/alber70g)
- Github: [@alber70g](https://github.com/alber70g)
## Contributing
Contributions, issues and feature requests are welcome!
Feel free to check
[issues page](https://github.com/alber70g/graphql-query-path/issues).
## Show your support
Give a ⭐️ if this project helped you!
---
_This README was generated by
[readme-md-generator](https://github.com/kefranabg/readme-md-generator)_