-
Notifications
You must be signed in to change notification settings - Fork 2
/
dynamoCache.js
101 lines (94 loc) · 2.55 KB
/
dynamoCache.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import { KeyValueCache } from 'apollo-server-caching';
// TODO add option for DAX here
// import AmazonDaxClient = require('aws-sdk/clients/dax');
import DynamoDB from 'aws-sdk/clients/dynamodb'
export class DynamoDBCache{
// client;
// tableOptions;
// defaultSetOptions = {
// ttl: 300,
// tableName: 'apollo-persisted-queries',
// };
// TODO extend to support dax and other options and define new type instead of any
// future options
// x-ray support e.g.
// daxClusterUrl > for DAX users
// cosistentRead > for strongly consistent read
// createTable > to create table on first request
// ttlAttributeName > in case ttl is not used
constructor(
serviceConfigOptions,
tableOptions,
) {
this.client = new DynamoDB(serviceConfigOptions);
// TODO for DAX
// dax = new AmazonDaxClient(serviceConfigOptions)
// this.daxClient = new DynamoDB.DocumentClient({service: dax });
this.tableOptions = tableOptions;
this.client.get = this.client.query.bind(this.client);
this.client.set = this.client.putItem.bind(this.client);
}
async set(
id,
data,
options
) {
// need dynamodb table as per
// aws dynamodb update-time-to-live --table-name TTLExample --time-to-live-specification "Enabled=true, AttributeName=ttl"
const { ttl, tableName } = Object.assign(
{},
this.defaultSetOptions,
this.tableOptions,
options,
);
let item =
ttl !== 0
? {
id: { S: id.toString() },
data: { S: data.toString() },
ttl: { S: ttl.toString() },
}
: {
id: { S: id.toString() },
data: { S: data.toString() },
};
// TODO mind 400kb limit per item here for for full query cache?
// TODO encrypt queries?
await this.client
.putItem({
TableName: tableName,
Item: item,
})
.promise();
}
async get(id){
const { tableName } = Object.assign(
{},
this.defaultSetOptions,
this.tableOptions,
);
const reply = await this.client
.query({
TableName: tableName,
KeyConditionExpression: '#id = :value',
ExpressionAttributeNames: {
'#id': 'id',
},
ExpressionAttributeValues: {
':value': { S: id },
},
})
.promise();
// reply is null if key is not found
if (
reply &&
reply.Items &&
reply.Items[0] &&
reply.Items[0].data &&
reply.Items[0].data.S
) {
return reply.Items[0].data.S;
}
return;
}
}