graphql-anywhere

npm version Build Status

Run a GraphQL query anywhere, without a GraphQL server or a schema. Just pass in one resolver. Use it together with graphql-tag.

npm install graphql-anywhere graphql-tag

I think there are a lot of potentially exciting use cases for a completely standalone and schema-less GraphQL execution engine. We use it in Apollo Client to read data from a Redux store with GraphQL.

Let's come up with some more ideas - below are some use cases to get you started!

API

import graphql from 'graphql-anywhere'

graphql(resolver, document, rootValue?, context?, variables?, options?)
  • resolver: A single resolver, called for every field on the query.

    • Signature is: (fieldName, rootValue, args, context, info) => any

  • document: A GraphQL document, as generated by the template literal from graphql-tag

  • rootValue: The root value passed to the resolver when executing the root fields

  • context: A context object passed to the resolver for every field

  • variables: A dictionary of variables for the query

  • options: Options for execution

Options

The last argument to the graphql function is a set of graphql-anywhere-specific options.

  • resultMapper: Transform field results after execution.

    • Signature is: (resultFields, resultRoot) => any

  • fragmentMatcher: Decide whether to execute a fragment. Default is to always execute all fragments.

    • Signature is: (rootValue, typeCondition, context) => boolean

Resolver info

info, the 5th argument to the resolver, is an object with supplementary information about execution. Send a PR or open an issue if you need additional information here.

  • isLeaf: A boolean that is true if this resolver is for a leaf field of the query, i.e. one that doesn't have a sub-selection.

  • resultKey: The key the result of this field will be put under. It's either the field name from the query, or the field alias.

  • directives: An object with information about all directives on this field. It's an object of the format { [directiveName]: { [argumentName]: value }}. So for example a field with @myDirective(hello: "world") will be passed as { myDirective: { hello: 'world' }}. Note that fields can't have multiple directives with the same name, as written in the GraphQL spec.

Utilities

See https://www.apollographql.com/docs/react/advanced/fragments.html for examples of how you might use these.

  • doc: a GraphQL document, as generated by the template literal from graphql-tag, typically either a query or a fragment.

  • data: an object of data to be filtered by the doc

Filter data according to doc.

  • doc: a GraphQL document, as generated by the template literal from graphql-tag, typically either a query or a fragment.

  • data: an object of data, as may have been filtered by doc.

Check that data is of the form defined by the query or fragment. Throw an exception if not.

  • doc: a GraphQL document, as generated by the template literal from graphql-tag, typically either a query or a fragment.

Generate a React propType checking function to ensure that the passed prop is in the right form.

Supported GraphQL features

Why do you even need a library for this? Well, running a GraphQL query isn't as simple as just traversing the AST, since there are some pretty neat features that make the language a bit more complex to execute.

If you come across a GraphQL feature not supported here, please file an issue.

Example: Filter a nested object

Example: Generate mock data

Example: Read from a Redux store generated with Normalizr

Example: Generate React components

You can use the resultMapper option to convert your results into anything you like. In this case, we convert the result fields into children for a React component:

Last updated