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

stacheql

v2.0.9

Published

simple and fast server-side cache for graphql

Downloads

13

Readme

stacheql

Node.js caching middleware for GraphQL queries, using Redis

StacheQL limits roundtrips to the GraphQL API by caching query results, as specified by the config object. All matching queries, full or partial, will pull results directly from the Redis cache, and only ping the GraphQL API if needed for additional results.

======================================================================

Why use StacheQL?

Every cache offers retrieval of exact matches-- StacheQL also offers:

  1. Subset query retrieval: For example, retrieving 5 of the top Italian restaurants from the cache using a previously queried/cached list of the top 10 Italian restaurants, obviating the HTTP request to the API.

  2. Superset query retrieval: For example, a query for the top 15 Italian restaurants after previously querying/caching a list of the top 10 Italian restaurants would result in returning the 10 items from the cache and pinging the API endpoint for the additional five. Both results would be stitched together and returned to the client, then cached in replacement of the previous subset.

======================================================================

Installation

$ npm install stacheql

or add stacheql to "dependencies" in your package.json, then npm install.

Requirements

Redis

To use StacheQL, you must set up a Redis data store as your cache. Refer to the documentation to get started.

StacheQL was written for use with ioredis, a Redis client for Node.js. If you prefer to use a different client, or to configure ioredis beyond the default, simply make those changes in stache.js.

Default configuration in stache.js:

const Redis = require("ioredis");
const redis = new Redis();

Express & JSON

StacheQL was written for the Express framework, and its middleware requires that body objects are parsed to JSON. The Express project recommends body-parser.

For HTTP requests sent to the GraphQL API, StacheQL requires that the request body is sent in JSON, NOT raw GraphQL.

======================================================================

Setup

const Stache = require("stacheql");
const stache = new Stache(config [, options]);

Sample config

const config = {
  cacheExpiration: 120,
  staticArgs: {
    term: String,
    location: Number,
    radius: Number,
  },
  flexArg: "limit",
  offsetArg: "offset",
  queryObject: "search",
  queryTypename: "Businesses",
};

cacheExpiration: Time (in seconds) for each query result to persist in the cache.

staticArgs: Query parameters in which values must match that of a prior query in order to validate a retrieval from the cache. Under the hood, staticArgs are combined to form the keys of the Redis cache. In the staticArgs object, the key represents the parameter name and the value represents the type. Mininum of one required.

flexArg: Single query parameter that will determine how many results are returned from the cache. This parameter must be of type Number.

offsetArg: Single query parameter that allows for an offset in the list of returned query results by a given amount, specifically for superset operations. This parameter must be of type Number.

queryObject: Name of the query object for your GraphQL API.

queryTypename: The __typename of that query object.

Options

A boolean value of false may be optionally passed as the second argument to disable superset operations. Superset operations combine results from the Redis cache with results from a new HTTP request, thus requiring a smaller response payload from the GraphQL API. This defaults to true.

// superset operations ENABLED
const stache = new Stache(config);

// superset operations DISABLED
const stache = new Stache(config, false);

======================================================================

Example Implementation

const stache = new Stache(config);

app.use(bodyParser.json());

app.post(
  "/api",
  stache.check, // StacheQL method
  (req, res, next) => {
    request.post(
      {
        url: API_URL,
        method: "POST",
        headers: {
          Authorization: "Bearer " + API_KEY,
        },
        json: true,
        body: req.body,
      },
      (err, response, body) => {
        res.locals.body = body; // must assign incoming data to "res.locals.body" and return next()
        return next();
      }
    );
  },
  stache.it // StacheQL method
);

StacheQL Methods

stache.check: Evaluates the request body to determine if there is a match on staticArgs in the Redis cache. If there is a match, then flexArg is used to determine what kind of match: an exact match, a subset match or a superset match. Exact and subset matches immediately return the needed results to the front end, bypassing the HTTP request. If no match or a superset match, the HTTP request is sent for the additional results.

stache.it: Handles the incoming data from the HTTP request, stored in res.locals.body. For superset matches, the pre-existing subset in the Redis cache is overwritten by the new superset data. Otherwise, a new entry is created.

======================================================================

Demo App

To see StacheQL in action using Yelp's public GraphQL API, clone this repo and check out the demo directory. First, request an API key from Yelp's Developer Beta and add a .env file to your demo directory. In the .env, set ACCESS_TOKEN equal to your API key. As detailed above, you will also need Redis up and running.

======================================================================

Issues

If you find an issue, let us know!

Contributers

Keith Avila | Natalie Klein | David Levien | Sam Ryoo