/graphql-apq

:dart: Automatic persisted queries (APQ) for any GraphQL server.

Primary LanguageTypeScriptMIT LicenseMIT

GraphQL APQ

Automatic persisted queries made easy.

build status coverage npm version sponsored by Taller


This library consists of a server-side implementation of the persisted queries protocol as presented by the Apollo Engine team.

Apollo Engine is a paid GraphQL gateway with many wonderful tools, and this project brings to the open-source world one of those tools.

Persisted queries was first brought up by the Apollo team, but relied mostly on complicated building process to achieve the full benefit proposed. Automatic persisted queries is a concept built on top of that idea, which allows for persisted queries to be registered in run-time.

How it works

  1. When the client makes a query, it will optimistically send a short (64-byte) cryptographic hash instead of the full query text.
  2. If the backend recognizes the hash, it will retrieve the full text of the query and execute it.
  3. If the backend doesn't recogize the hash, it will ask the client to send the hash and the query text to it can store them mapped together for future lookups. During this request, the backend will also fulfill the data request.

This library is a server implementation for use with any GraphQL server.

You can use any client-side implementation, as long as it follows the same protocol, but we strongly recommend using the apollo-link-persisted-queries project.

Installation

npm install graphql-apq --save

Usage

This project currently provides a core system for handling persisted queries and an express middleware to integrate it to a GraphQL server of choice. It will eventually also provide an extension to the Apollo Server project, as soon as extensions are implemented in that project.

Middleware

import persistedQueries from 'graphql-apq/lib/express'
import express from 'express'
import bodyParser from 'body-parser'
import { graphqlExpress } from 'apollo-server-express'

const schema = // ... define or import your schema here!
const PORT = 3000;

const app = express();

app
  .use('/graphql', bodyParser.json(), persistedQueries(), graphqlExpress({ schema }))
  .listen(PORT)

Options

You can alter some of APQ's default behavior by providing an object of options to the middleware initialization as follows:

cache

A cache object implementing at least the following interface:

interface CacheInterface {
  get: (key: string) => string | null | Promise<string | null>
  set: (key: string, value: string) => void | Promise<void>
  has: (key: string) => boolean | Promise<boolean>
}

Defaults to an instance of memory-cache. Can be modified to provide a more specialized caching system, such as node-redis.

resolveHash

A reducer from an operation to the hash to use. Defaults to retrieving the hash from operation.extensions.persistedQuery.sha256Hash.