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
"West Side Story"
Second console.log
for actors
[ { "name": "Rita Moreno" }, { "name": "Natalie Wood" }, { "name": "George Chakiris" }, { "name": "Richard Beymer" } ]
Third console.log
for richard
{ "name": "Richard Beymer" }