npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ibm-graphql-query-generator

v1.3.0

Published

Randomly generate a GraphQL query using a GraphQL schema

Downloads

2,094

Readme

GitHub last commit npm

GraphQL Query Generator

This library will generate randomized GraphQL queries from a given schema.

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:

const { generateRandomQuery } = require("ibm-graphql-query-generator")

Minimal working example

All arguments are exposed as variables. Providers can be passed to provide values for these variables. For example:

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:

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:

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, this library exposes that argument as a variable. The names of these variables reflect the type and field that the argument applies to, as well as the argument name like so:

<type>__<fieldName>__<argumentName>

Alternatively, you can match using:

<type>__<fieldName>

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 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, 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.