5.1.0 • Published 11 months ago

@envelop/response-cache v5.1.0

Weekly downloads
-
License
MIT
Repository
github
Last release
11 months ago

@envelop/response-cache

  • Skip the execution phase and reduce server load by caching execution results in-memory.
  • Customize cache entry time to live based on fields and types within the execution result.
  • Automatically invalidate the cache based on mutation selection sets.
  • Customize invalidation through the cache api (e.g. listen to a database write log).
  • Implement your own global cache (e.g. using Redis) by implementing the Cache interface.

Check out the GraphQL Response Cache Guide for more information

Getting Started

yarn add @envelop/response-cache

Usage Example

import { envelop } from '@envelop/core';
import { useResponseCache } from '@envelop/response-cache';

const getEnveloped = envelop({
  plugins: [
    // ... other plugins ...
    useResponseCache(),
  ],
});

Recipes

Cache with maximum TTL

import { envelop } from '@envelop/core';
import { useResponseCache } from '@envelop/response-cache';

const getEnveloped = envelop({
  plugins: [
    // ... other plugins ...
    useResponseCache({
      ttl: 2000, // cached execution results become stale after 2 seconds
    }),
  ],
});

Cache with custom TTL per object type

import { envelop } from '@envelop/core';
import { useResponseCache } from '@envelop/response-cache';

const getEnveloped = envelop({
  plugins: [
    // ... other plugins ...
    useResponseCache({
      ttl: 2000,
      ttlPerType: {
        // cached execution results that contain a `Stock` object become stale after 500ms
        Stock: 500,
      },
    }),
  ],
});

Cache with custom TTL per schema coordinate

import { envelop } from '@envelop/core';
import { useResponseCache } from '@envelop/response-cache';

const getEnveloped = envelop({
  plugins: [
    // ... other plugins ...
    useResponseCache({
      ttl: 2000,
      ttlPerSchemaCoordinate: {
        // cached execution results that select the `Query.user` field become stale after 100ms
        'Query.rocketCoordinates': 100,
      },
    }),
  ],
});

Cache based on session/user

import { envelop } from '@envelop/core';
import { useResponseCache } from '@envelop/response-cache';

const getEnveloped = envelop({
  plugins: [
    // ... other plugins ...
    useResponseCache({
      ttl: 2000,
      // context is the GraphQL context used for execution
      session: context => String(context.user?.id),
    }),
  ],
});

Disable cache based on session/user

import { envelop } from '@envelop/core';
import { useResponseCache } from '@envelop/response-cache';

const getEnveloped = envelop({
  plugins: [
    // ... other plugins ...
    useResponseCache({
      ttl: 2000,
      // context is the GraphQL context used for execution
      enabled: context => context.user?.role !== 'admin',
    }),
  ],
});

Prevent caching of sensitive information

import { envelop } from '@envelop/core';
import { useResponseCache } from '@envelop/response-cache';

const getEnveloped = envelop({
  plugins: [
    // ... other plugins ...
    useResponseCache({
      ttl: 2000,
      // never cache responses that include a RefreshToken object type.
      ignoredTypes: ['RefreshToken'],
    }),
  ],
});

Customize the fields that are used for building the cache ID

import { envelop } from '@envelop/core';
import { useResponseCache } from '@envelop/response-cache';

const getEnveloped = envelop({
  plugins: [
    // ... other plugins ...
    useResponseCache({
      ttl: 2000,
      // use the `_id` instead of `id` field.
      idFields: ['_id'],
    }),
  ],
});

Disable automatic cache invalidation via mutations

import { envelop } from '@envelop/core';
import { useResponseCache } from '@envelop/response-cache';

const getEnveloped = envelop({
  plugins: [
    // ... other plugins ...
    useResponseCache({
      ttl: 2000,
      // some might prefer invalidating based on a database write log
      invalidateViaMutation: false,
    }),
  ],
});

Invalidate Cache based on custom logic

import { envelop } from '@envelop/core';
import { useResponseCache, createInMemoryCache } from '@envelop/response-cache';
import { emitter } from './eventEmitter';

// we create our cache instance, which allows calling all methods on it
const cache = createInMemoryCache();

const getEnveloped = envelop({
  plugins: [
    // ... other plugins ...
    useResponseCache({
      ttl: 2000,
      // we pass the cache instance to the request.
      cache,
    }),
  ],
});

emitter.on('invalidate', resource => {
  cache.invalidate([
    {
      typename: resource.type,
      id: resource.id,
    },
  ]);
});

Customize how cache ids are built

import { envelop } from '@envelop/core';
import { useResponseCache, createInMemoryCache } from '@envelop/response-cache';
import { emitter } from './eventEmitter';

// we create our cache instance, which allows calling all methods on it
const cache = createInMemoryCache({
  // in relay we have global unique ids, no need to use `typename:id`
  makeId: (typename, id) => id ?? typename,
});

const getEnveloped = envelop({
  plugins: [
    // ... other plugins ...
    useResponseCache({
      ttl: 2000,
      // we pass the cache instance to the request.
      cache,
    }),
  ],
});
5.1.0

11 months ago

4.0.7

1 year ago

4.0.6

1 year ago

5.0.1

11 months ago

5.0.0

12 months ago

4.0.8

1 year ago

4.0.5

1 year ago

4.0.4

1 year ago

4.0.1

2 years ago

4.0.0

2 years ago

4.0.3

2 years ago

4.0.2

2 years ago

2.4.0

2 years ago

3.2.0

2 years ago

3.1.0

2 years ago

3.0.2

2 years ago

3.0.1

2 years ago

3.0.0

2 years ago

2.3.3

2 years ago

2.3.2

2 years ago

2.3.0

2 years ago

2.3.1

2 years ago

2.2.0

2 years ago

2.1.1

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago

2.0.0

2 years ago

2.1.0

2 years ago

0.6.0

2 years ago

0.5.0

3 years ago

0.5.1

2 years ago

0.3.0

3 years ago

0.4.0

3 years ago

0.2.1

3 years ago

0.2.0

3 years ago

0.1.0

3 years ago