Skip to main content

Introducing GraphQL Paper

GraphQL Paper is a flexible in-memory store based on a provided GraphQL Schema.

In testing and development it is handy to have a store that reflects the current state of the world, handles connections between data, and updates via mutations. While GraphQL Paper integrates well with the rest of graphql-mocks, it can also be used on its own.

✨ Features

  • Built and based on GraphQL
  • Works in the Browser and Node JS
  • Works without graphql-mocks with support for the official default GraphQL resolvers
  • Written in TypeScript
  • Support and integration with graphql-mocks
  • Support for relationships and connections between types
  • Immutable
  • Accessible via native js APIs
  • Hooks (docs)
  • Events (docs)
  • Transaction Operations (docs)
  • Validations (docs)
  • API Query Imports

Coming Soon:

  • Time-travel debugging, store snapshots, and the ability to restore to existing store snapshots
  • Specialized factory operation with support for various states and scenarios, with functional factories currently working now (docs)

API Reference

There is the API reference available for the graphql-paper package.

Integration with graphql-mocks

Check out the guide for using graphql-mocks with GraphQL Paper.

Documents and the Store

With GraphQL Paper a Document is a POJO (plain-old javascript object) that represents a concrete GraphQL type, it is not an instance.

For example an Actor GraphQL type:

type Actor {
title: String!
}

Could have a corresponding Document:

{
title: 'Jurassic Park'
}

Documents are stored in an array on the DocumentStore keyed by the GraphQL type. Based on the previous example a basic store containing our document could look like:

{
Actor: [{ title: 'Jurassic Park' }]
}

This is a simplistic, but realistic example, of how data is stored. Learn how to query and mutate the store (see below for a quick example of both). Check out the technical notes for a closer look at how everything works.

A Quick Example

Here's a quick glimpse at what is possible with GraphQL Paper:

import { Paper } from "graphql-paper";

const graphqlSchema = `
schema {
query: Query
}

type Query {
films: [Film!]!
}

type Film {
title: String!
year: Int!
actors: [Actor!]!
}

type Actor {
name: String!
}
`;

const paper = new Paper(graphqlSchema);

async function run() {
const westSideStory = await paper.mutate(({ create }) => {
// Create a Film with several actors
const film = create("Film", {
title: "West Side Story",
year: 1961,
actors: [
{ name: "Rita Moreno" },
{ name: "Natalie Wood" },
{ name: "George Chakiris" },
{ name: "Richard Beymer" },
],
});

// return film to be available outside the `mutate`
return film;
});

// pull results off the returned result
const { title, actors } = westSideStory;

// FIRST console.log
console.log(title);

// SECOND console.log
console.log(actors);

// can lookup results on the `Paper` instance, too
const richard = paper.data.Actor.find(
({ name }) => name === "Richard Beymer"
);

// THIRD console.log
console.log(richard);
}

// kick off async function
run();

First console.log for title

Result:
"West Side Story"

Second console.log for actors

Result:
[
  {
    "name": "Rita Moreno"
  },
  {
    "name": "Natalie Wood"
  },
  {
    "name": "George Chakiris"
  },
  {
    "name": "Richard Beymer"
  }
]

Third console.log for richard

Result:
{
  "name": "Richard Beymer"
}