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

mini-graphql-http-client

v2.0.0

Published

Minimalistic (0 dependencies, 1Kb) GraphQL client for browsers and node.js with memory caching support

Downloads

10

Readme

mini-graphql-http-client

Minimalistic (0 dependencies, 1Kb) GraphQL client for browsers and node.js with memory caching support

gzip size brotli size

Why this project exists?

ApolloClient is a super cool GraphQL client. Pluggable, universal, well documented, multi-protocol, smart caching, insane amount of features, etc. You should use it.

However, it was too much for our humble needs. All we wanted is to do HTTP JSON calls which are cached in memory.

ApolloClient:

  • is more than 30Kb of Gzipped JavaScript;
  • it can't easily cache CMS queries like this: { about_us_page { title description cta cta_action } };
  • difficult to grasp how it behaves without deep diving into the (amazing!) docs.

There is a handful of alternatives: https://github.com/chentsulin/awesome-graphql#clients

Although, half of them are bound to a framework (like React or AWS Amplify), another half don't have all the features we need: simple caching, small size, HTTP, no dependencies. Thus, this project was born.

MiniGraphqlHttpClient:

  • 1Kb of Gzipped JavaScript;
  • Caches the whole query without parsing it;
  • Newbie friendly, straightforward to use.

How caching works

TL;DR: It's a dumb map. Key: 32bit hash of query string+variables, Value: JSON response.

Note! This is a key difference to all the other GraphQL client modules.

By default, it caches every GraphQL query (not mutation!) response to the memory forever. You can adjust the caching duration(s). Responses containing errors are not cached obv.

On every request a 32bit hash (up to 4,294,967,295 unique values) of your query+variables is generated and used as a key in a key-value map. This should be enough for a few thousand cache entries before seeing hash clashes.

So, if the MiniGraphqlHttpClient sees identical GraphQL HTTP request (same query+variables) a cached value is returned, no HTTP requests performed.

Usage

Install:

npm i mini-graphql-http-client

Creating the client object instance

Node.js

const MiniGraphqlHttpClient = require("mini-graphql-http-client");

const graphqlClient = MiniGraphqlHttpClient({
  uri: "example.com/graphql",
  fetch: require("node-fetch"),
});

Modern browsers

import MiniGraphqlHttpClient from "mini-graphql-http-client";

const graphqlClient = MiniGraphqlHttpClient({
  uri: "example.com/graphql",
});

IE browser

You must polyfil fetch and ES6 Map global variables.

Querying

try {
  const { data, errors } = await graphqlClient.query({
    query: `{ hero { name height mass } }`,
  });
  if (errors && errors.length)
    console.error("GraphQL response contains errors", errors);

  if (data && data.hero)
    console.log(`Hero ${data.hero.name} height is ${data.hero.height}`);
} catch (e) {
  console.error("HTTP request failed", e);
}

API

MiniGraphqlHttpClient()

Example showing all available options.

const graphqlClient = MiniGraphqlHttpClient({
  // This is the only required argument
  uri: "example.com/graphql", // Your GraphQL endpoint.

  // All the below are optional.

  // The HTTP method of the requests.
  method: "PUT", // default is "POST"

  // The `fetch` implementation.
  fetch: require("unfetch"), // Will attempt to use global `fetch`.

  // Number of retries if HTTP request fails - network error or 5xx response.
  retry: 2, // Default is 0. The value 2 would mean we do total 3 attempts. 
    
  // Arbitrary headers to send with every HTTP request.
  headers: { Token: mySecureToken }, // Only "content-type":"application/json" is added by default.

  // The well known `fetch` option. https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
  credentials: "omit", // default is "include"

  // Control various aspect of the cache via this argument.
  cache: {
    // For how long a query response will be cached.
    duration: 60 * 1000, // default is Number.MAX_SAFE_INTEGER, i.e. indefinite
    // Cache map itself. By default it's ES6 Map.
    map: new Map(), // Provide your own cache map. Useful to reuse cache across several client instances. Overrides `jsonCache`.
    // Your cache initial state as a POJO (Plain Old JavaScript Object). Use it for hydration.
    jsonCache: [], // Initialise your cache with a JSON data. See cacheToJSON() method.
  },

  // Hook callbacks. Useful for logging or debugging purposes.
  hooks: {
    // A callback function called before each request.
    request({ query, variables, cacheDuration, uri, fetchOptions }) {
      /*...*/
    },
    // A callback function called after each request.
    response({
      query,
      variables,
      cacheDuration,
      uri,
      fetchOptions,
      response,
      json,
      error,
    }) {
      /*...*/
    },
  },
});

Methods

Let's look what you can do with the graphqlClient from the above.

.query({...})

Send an HTTP request containing JSON data with two properties: query and variables.

const { data, errors } = await graphqlClient.query({
  // This is the only required argument
  query: `query($input: OrdersInput) { orders(input: $input) { totalAmount items { id price title } } }`,

  // All the below are optional.

  // GraphQL variables
  variables: { input: { from: "2020-07-01", to: "2021-06-30" } },

  // Additional arbitrary request headers.
  headers: { version: "2" },

  // Override the default caching duration for this particular query.
  cacheDuration: 60 * 60_000,
});

.mutate({...})

Send an HTTP request containing JSON data with two properties: query (not "mutation"!) and variables. The responses are never cached.

const { data, errors } = await graphqlClient.mutate({
  // This is the only required argument
  mutation: `mutation($input: CreateOrderInput) { createOrder(input: $input) { success code message } }`,

  // All the below are optional.

  // GraphQL variables
  variables: { input: { user_id: "DABE25B9-C1EF-4087-880B-CD97E3E38393" } },

  // Additional arbitrary request headers.
  headers: { version: "2" },
});

.clearCache()

Clears the cache map.

graphqlClient.clearCache();

.cacheToJSON()

Get POJO of your cache (perhaps on the server?).

const cachePojo = graphqlClient.cacheToJSON();

Use the POJO to create a new client (perhaps in the browser?).

const graphqlClient = MiniGraphqlHttpClient({
  uri: "example.com/graphql",
  cache: { jsonCache: cachePojo },
});

How-To's

Log every request and response

Use the hooks.

const graphqlClient = MiniGraphqlHttpClient({
  uri: "example.com/graphql",

  hooks: {
    request: ({ query }) => console.log(query),
    response: ({ json, error }) =>
      error ? console.log(error) : console.log(json),
  },
});

Having the same cache in two client instances

const cacheMap = new Map();

const graphqlClient1 = MiniGraphqlHttpClient({
  uri: "example.com/graphql",
  cache: { map: cacheMap },
});
const graphqlClient2 = MiniGraphqlHttpClient({
  uri: "example.com/graphql",
  cache: { map: cacheMap },
});