Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/IBM/graphql-query-generator
Randomly generates GraphQL queries from a GraphQL schema
https://github.com/IBM/graphql-query-generator
Last synced: 4 days ago
JSON representation
Randomly generates GraphQL queries from a GraphQL schema
- Host: GitHub
- URL: https://github.com/IBM/graphql-query-generator
- Owner: IBM
- License: mit
- Created: 2020-05-05T18:41:38.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2023-01-06T07:40:00.000Z (almost 2 years ago)
- Last Synced: 2024-11-01T23:37:33.320Z (7 days ago)
- Language: TypeScript
- Homepage:
- Size: 2.07 MB
- Stars: 337
- Watchers: 13
- Forks: 27
- Open Issues: 43
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-list - graphql-query-generator
- awesome-starred - IBM/graphql-query-generator - Randomly generates GraphQL queries from a GraphQL schema (others)
README
![GitHub last commit](https://img.shields.io/github/last-commit/ibm/graphql-query-generator.svg?style=flat) [![npm](https://img.shields.io/npm/v/ibm-graphql-query-generator.svg?style=flat)](https://www.npmjs.com/package/ibm-graphql-query-generator)
# GraphQL Query Generator
This library will generate randomized [GraphQL](https://graphql.org/) queries from a given schema.
![](./images/diagram.png)
It can be used in a few ways:
- _Engineering_: If you operate a GraphQL service, you might use this library to:
- develop a static test suite of GraphQL queries
- develop a battery of queries to test the effect of performance improvements
- _Scientific_: Understand the characteristics of various GraphQL services## Usage
Install the library using:
```
npm i ibm-graphql-query-generator
```Usage typically relies on the `generateRandomQuery` function, which can be imported like this:
```javascript
const { generateRandomQuery } = require("ibm-graphql-query-generator")
```### Minimal working example
All [arguments](https://facebook.github.io/graphql/draft/#sec-Language.Arguments) are exposed as [variables](https://facebook.github.io/graphql/draft/#sec-Language.Variables). _Providers_ can be passed to provide values for these variables. For example:
```javascript
const { generateRandomQuery } = require("ibm-graphql-query-generator")const { buildSchema, print } = require("graphql")
const schema = `
type Query {
getUser(name: String!): User
getCompany(companyName: String!): Company
}type User {
firstName: String
lastName: String
employer: Company
friends: [User]
}type Company {
name: String
CEO: User
employees: [User]
}
`const configuration = {
depthProbability: 0.5,
breadthProbability: 0.5,
providerMap: {
"*__*__name": () => {
const nameList = ["Alfred", "Barbara", "Charles", "Dorothy"]return nameList[Math.floor(Math.random() * nameList.length)]
},
"*__*__companyName": () => {
const companyNameList = [
"All Systems Go",
"Business Brothers",
"Corporate Comglomerate Company",
"Data Defenders"
]return companyNameList[
Math.floor(Math.random() * companyNameList.length)
]
}
}
}const { queryDocument, variableValues, seed } = generateRandomQuery(
buildSchema(schema),
configuration
)console.log(print(queryDocument))
console.log(variableValues)
```## Example configurations
We provide sample query generators for the following APIs:
- [GitHub API](https://github.com/IBM/graphql-query-generator/tree/master/examples/github-query-generator)
- [Yelp API](https://github.com/IBM/graphql-query-generator/tree/master/examples/yelp-query-generator)## Generating random queries
This library exposes two functions for generating random GraphQL queries:
- `getRandomQuery(schema: GraphQLSchema, config: Configuration)`: Produces a random query from the given schema, and considering the passed configuration.
- `getRandomMutation(schema: GraphQLSchema, config: Configuration)`: Produces a random mutation from the given schema, and considering the passed configuration.### Configuration
Functions of this library accept a configuration object with the following properties:
- `depthProbability` (type: `number`, default: `0.5`): The probability (from `0` to `1`) that, if existent, fields that themselves have subfields are selected at every level of the generated query. The number of so selected fields depends on the `breadthProbability`.
- `breadthProbability` (type: `number`, default: `0.5`): The probability (from `0` to `1`) that a field (nested or flat) is selected at every level of the generated query.
- `maxDepth` (type: `number`, default: `5`): The maximum depths of the query / mutation to generate. This library ensures that leave nodes do not require children fields to be selected.
- `ignoreOptionalArguments` (type: `boolean`, default: `true`): If set to `true`, non-mandatory arguments will not be included in the generated query / mutation.
- `argumentsToIgnore` (type: `string[]`, default: `[]`): List of argument names that should be ignored in any case. If non-null arguments are configured to be ignored, an error will be thrown.
- `argumentsToConsider` (type: `string[]`, default: `[]`): List of argument names that should be considered, even if the argument is optional and `ignoreOptionalArguments` is set to `true`.
- `providerMap` (type: `{[varNameQuery: string]: any | ProviderFunction }`, default: `{}`): Map of values or functions to provide values for the variables present in the generated query / mutation. See details below.
- `providePlaceholders` (type: `boolean`, default: `false`): If enabled, instead of defaulting to `null`, placeholder values of correct type are provided for variables. Specifically, the placeholders are `10` for type `Int`, `10.0` for type `Float`, `true` for type `Boolean`, and `"PLACEHOLDER"` for types `String` and `ID`, and custom scalars.
- `considerInterfaces` (type: `boolean`, default: `false`): Create queries containing interfaces (by calling fields in the interfaces and/or creating fragments on objects implementing the interfaces)
- `considerUnions` (type: `boolean`, default: `false`): Create queries containing unions (by creating fragments on objects of the unions)
- `seed` (type: `number`, optional): Allows the generator to produce queries deterministically based on a random number generator seed. If no seed is provided, a random seed will be provided. The seed that is used to produce the query, whether user-provided or randomly generated, will be included in the output.
- `pickNestedQueryField` (type: `boolean`, default: `false`): Guarantees that the generator will pick at least one nested field.Example:
```javascript
const cfg = {
'depthProbability': 0.5,
'breadthProbability': 0.5,
'maxDepth': 5,
'ignoreOptionalArguments': true,
'argumentsToIgnore': [],
'argumentsToConsider': [],
'providerMap': {'*__*__*': null},
'considerInterfaces': false,
'considerUnions': false,
'seed': 1,
'pickNestedQueryField': false
}
```### Provider map
Whenever a randomly generated query or mutation requires an [argument](https://facebook.github.io/graphql/draft/#sec-Language.Arguments), this library exposes that argument as a [variable](https://facebook.github.io/graphql/draft/#sec-Language.Variables). The names of these variables reflect the type and field that the argument applies to, as well as the argument name like so:
```
____
```Alternatively, you can match using:
```
__
```In this case, the provider function returns an object where multiple arguments are present.
The `providerMap` contains values or value producing functions for the variables in a query.
The keys of the `providerMap` are either the exact name of the variable or a wildcard where either the `type`, `fieldName`, and/or `argumentName` are replaced by a `*`. For example, the key `*__*__limit` matches all variables for arguments of name `limit`, no matter for what field the argument is used or in which type. If no `providerMap` is passed, a default map `{'*__*__*': null}` is used, which provides a `null` value to all variables (Note: this can be problematic if an argument defines a [non-null](https://facebook.github.io/graphql/draft/#sec-Type-System.Non-Null) value).
The values of the `providerMap` are either the concrete argument values, or a function that will be invoked to provide that value. A provider function will get passed a map of all already provided variable values, which allows to provide values based on previous ones. It will also get passed the argument type (as a `GraphQLNamedType`) as a second argument.
This library also exposes a function `matchVarName(query: string, candidates: string[]): string` that, from a given list of variable names and/or variable name queries, finds the one matching the given variable name or query.
Note that for variables with an [enumeration type](https://graphql.org/learn/schema/#enumeration-types), this library automatically chooses one value at random.
### Errors
Generating random queries or mutations may fail in some cases:
- An error is thrown if a query hits the defined `maxDepth`, but there are only fields with children to choose from. Choosing such a field but then not choosing a sub-field for it (due to the `maxDepth` constraint) would result in an invalid query and thus causes this library to throw an error.
- An error is thrown if there is no provider defined for a variable in the generated query.## Citing this library
If you use this library in a scientific publication, please cite:
1. The library, as: _IBM, graphql-query-generator, 2020. https://github.com/IBM/graphql-query-generator_.
2. The work in which we introduced it, as: _Cha, Wittern, Baudart, Davis, Mandel, and Laredo. A Principled Approach to GraphQL Query Cost Analysis. ESEC/FSE 2020_.