Skip to content

Commit

Permalink
feat(rest-datasource): add apollo-server-cache-redis-cluster package
Browse files Browse the repository at this point in the history
  • Loading branch information
eberhara committed Oct 4, 2018
1 parent bb0537b commit 1db59d9
Show file tree
Hide file tree
Showing 9 changed files with 1,408 additions and 1,163 deletions.
2,382 changes: 1,219 additions & 1,163 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"apollo-server": "file:packages/apollo-server",
"apollo-server-cache-memcached": "file:packages/apollo-server-cache-memcached",
"apollo-server-cache-redis": "file:packages/apollo-server-cache-redis",
"apollo-server-cache-redis-cluster": "file:packages/apollo-server-cache-redis-cluster",
"apollo-server-caching": "file:packages/apollo-server-caching",
"apollo-server-cloudflare": "file:packages/apollo-server-cloudflare",
"apollo-server-core": "file:packages/apollo-server-core",
Expand All @@ -62,6 +63,7 @@
"@types/fibers": "0.0.30",
"@types/graphql": "14.0.1",
"@types/hapi": "17.6.1",
"@types/ioredis": "^4.0.1",
"@types/jest": "23.3.3",
"@types/koa-multer": "1.0.0",
"@types/koa-router": "7.0.32",
Expand Down Expand Up @@ -89,6 +91,7 @@
"graphql-tools": "3.1.1",
"hapi": "17.6.0",
"husky": "0.14.3",
"ioredis-mock": "^4.0.0",
"jest": "23.6.0",
"jest-junit": "5.2.0",
"jest-matcher-utils": "23.6.0",
Expand Down
6 changes: 6 additions & 0 deletions packages/apollo-server-cache-redis-cluster/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*
!src/**/*
!dist/**/*
dist/**/*.test.*
!package.json
!README.md
51 changes: 51 additions & 0 deletions packages/apollo-server-cache-redis-cluster/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
## RedisClusterCache

[![npm version](https://badge.fury.io/js/apollo-server-cache-redis-cluster.svg)](https://badge.fury.io/js/apollo-server-cache-redis-cluster)
[![Build Status](https://circleci.com/gh/apollographql/apollo-server.svg?style=svg)](https://circleci.com/gh/apollographql/apollo-server)

This package exports an implementation of `KeyValueCache` that allows using Redis as a backing store for resource caching in [Data Sources](https://www.apollographql.com/docs/apollo-server/v2/features/data-sources.html).

## Usage

### Single instance or sentinels

```js
const { RedisCache } = require('apollo-server-cache-redis-cluster');

const server = new ApolloServer({
typeDefs,
resolvers,
cache: new RedisClusterCache({
host: 'redis-server',
// Options are passed through to the Redis client
}),
dataSources: () => ({
moviesAPI: new MoviesAPI(),
}),
});
```

### Cluster

```js
const { RedisClusterCache } = require('apollo-server-cache-redis-cluster');

const server = new ApolloServer({
typeDefs,
resolvers,
cache: new RedisClusterCache(
[{
host: 'redis-server',
// Options are passed through to the Redis cluster client
}],
{
// Cluster options are passed through to the Redis cluster client
}
),
dataSources: () => ({
moviesAPI: new MoviesAPI(),
}),
});
```

For documentation of the options you can pass to the underlying redis client, look [here](https://github.com/luin/ioredis).
30 changes: 30 additions & 0 deletions packages/apollo-server-cache-redis-cluster/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "apollo-server-cache-redis-cluster",
"version": "0.0.1",
"author": "[email protected]",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/apollographql/apollo-server/tree/master/packages/apollo-server-cache-redis-cluster"
},
"homepage": "https://github.com/apollographql/apollo-server#readme",
"bugs": {
"url": "https://github.com/apollographql/apollo-server/issues"
},
"scripts": {
"clean": "rm -rf dist",
"compile": "tsc",
"prepare": "npm run clean && npm run compile"
},
"main": "dist/index.js",
"types": "dist/index.d.ts",
"engines": {
"node": ">=6"
},
"dependencies": {
"apollo-server-caching": "file:../apollo-server-caching",
"apollo-server-env": "file:../apollo-server-env",
"dataloader": "^1.4.0",
"ioredis": "^4.0.0"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// use mock implementations for underlying databases
jest.mock('ioredis', () => require('ioredis-mock'));
jest.useFakeTimers(); // mocks out setTimeout that is used in ioredis-mock

import { RedisCache } from '../index';
import { testKeyValueCache } from '../../../apollo-server-caching/src/__tests__/testsuite';

testKeyValueCache(new RedisCache({ host: 'localhost' }));
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// use mock implementations for underlying databases
jest.mock('ioredis', () => require('ioredis-mock'));
jest.useFakeTimers(); // mocks out setTimeout that is used in ioredis-mock

import { RedisClusterCache } from '../index';
import { testKeyValueCache } from '../../../apollo-server-caching/src/__tests__/testsuite';

testKeyValueCache(
new RedisClusterCache([{ host: 'localhost' }], { scaleReads: 'master' }),
);
72 changes: 72 additions & 0 deletions packages/apollo-server-cache-redis-cluster/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { KeyValueCache } from 'apollo-server-caching';
import Redis, { ClusterOptions, ClusterNode, RedisOptions } from 'ioredis';
import { promisify } from 'util';
import DataLoader from 'dataloader';

export class RedisCache implements KeyValueCache {
protected client: any;
readonly defaultSetOptions = {
ttl: 300,
};

protected loader: DataLoader<string, string>;

constructor(options?: RedisOptions) {
const client = new Redis(options);
client.mget = promisify(client.mget).bind(client);
client.set = promisify(client.set).bind(client);
client.flushdb = promisify(client.flushdb).bind(client);
client.quit = promisify(client.quit).bind(client);

this.client = client;

this.loader = new DataLoader(keys => this.client.mget(keys), {
cache: false,
});
}

async set(
key: string,
data: string,
options?: { ttl?: number },
): Promise<void> {
const { ttl } = Object.assign({}, this.defaultSetOptions, options);
await this.client.set(key, data, 'EX', ttl);
}

async get(key: string): Promise<string | undefined> {
const reply = await this.loader.load(key);
// reply is null if key is not found
if (reply !== null) {
return reply;
}
return;
}

async flush(): Promise<void> {
await this.client.flushdb();
}

async close(): Promise<void> {
await this.client.quit();
return;
}
}

export class RedisClusterCache extends RedisCache {
constructor(nodes: ClusterNode[], options?: ClusterOptions) {
super();
const client = new Redis.Cluster(nodes, options);

client.mget = promisify(client.mget).bind(client);
client.set = promisify(client.set).bind(client);
client.flushdb = promisify(client.flushdb).bind(client);
client.quit = promisify(client.quit).bind(client);

this.client = client;

this.loader = new DataLoader(keys => this.client.mget(keys), {
cache: false,
});
}
}
9 changes: 9 additions & 0 deletions packages/apollo-server-cache-redis-cluster/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist"
},
"include": ["src/**/*"],
"exclude": ["**/__tests__", "**/__mocks__"]
}

0 comments on commit 1db59d9

Please sign in to comment.