-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
133 lines (121 loc) · 4.66 KB
/
index.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// This example of graphql-flatten-path can be run directly with a later
// version of Node (supporting more modern JS features).
const { graphql } = require('graphql');
const { makeExecutableSchema } = require('graphql-tools');
const { applyMiddleware } = require('graphql-middleware');
// Make sure to run "npm link graphql-flatten-path" in this directory.
// graphql-flatten-path isn't saved in package.json.
const flatten = require('graphql-flatten-path');
// Sample data normally found in a database.
const db = {
transactions: [
{ id: 'AA4FBAgPDAIPDgEMBA8DBw', merchantId: 'CAYGCAYKAwYDBw8JBA8LDw', amount: 479.64, timestamp: 1549494790 },
{ id: 'BggDBwUICwYHAwwOBA0CDg', merchantId: 'Aw4ADQUMAQkPAwsMBAkKDg', amount: 613.57, timestamp: 1549411990 },
{ id: 'BQsKAQMICg0ABA0GBAYHCg', merchantId: 'CAYGCAYKAwYDBw8JBA8LDw', amount: 818.92, timestamp: 1548893590 },
{ id: 'DAwLCAwNDw8IDwQOBAEDBw', merchantId: 'AQwDDgAIBwABCAQBBA8IBQ', amount: 410.01, timestamp: 1546819990 },
{ id: 'BQcACAYFDA4ABgYMBAYHDw', merchantId: 'AgQJCAwOCQgADAMPBAENBw', amount: 272.13, timestamp: 1517962390 },
],
merchants: [
{ id: 'CAYGCAYKAwYDBw8JBA8LDw', name: 'Kozey - Gutmann, Inc' },
{ id: 'Aw4ADQUMAQkPAwsMBAkKDg', name: 'Hane Group, LLC' },
{ id: 'AQwDDgAIBwABCAQBBA8IBQ', name: 'Bogisich - Goldner' },
{ id: 'AgQJCAwOCQgADAMPBAENBw', name: 'Schamberger, Reinger and Schmidt' },
],
};
const typeDefs = `
type Merchant {
id: ID!
name: String!
transactions: [Transaction!]!
}
type Transaction {
id: ID!
merchant: Merchant!
amount: String!
date: String! # You want an official DateTime scalar too, right?
}
type Query {
merchant(id: ID!): Merchant!
transactions: [Transaction!]!
}
`;
// The usage section of the README said to add graphql-flatten-path to
// the resolvers, but they're missing here! Have we been lied to?!
const resolvers = {
Query: {
merchant: async (parent, args, context, info) => {
return context.db.merchants.find((merchant) => {
return merchant.id === args.id;
});
},
transactions: async (parent, args, context, info) => {
return context.db.transactions;
},
},
Merchant: {
transactions: async (parent, args, context, info) => {
return context.db.transactions.filter((transaction) => {
return transaction.merchantId === parent.id;
});
},
},
Transaction: {
merchant: async (parent, args, context, info) => {
return context.db.merchants.find((merchant) => {
return merchant.id === parent.merchantId;
});
},
amount: async (parent, args, context, info) => {
const amount = parseFloat(parent.amount).toFixed(2);
return `$${amount}`;
},
date: async (parent, args, context, info) => {
return new Date(parent.timestamp * 1000).toUTCString();
},
},
};
// There it is! We're using a "middleware" resolver to apply this logic
// to every resolver. I could never lie to you.
const logResponseTimeMiddleware = async (resolver, parent, args, context, info) => {
const path = flatten(info.path, info.operation).join('.');
const result = await resolver(parent, args, context, info);
const executionResponseTime = Date.now() - context.executionStartTime;
if (executionResponseTime > 900) {
console.warn(`WARNING: ${path} ==> ${executionResponseTime}ms ∙ exceeds the threshold by ${executionResponseTime - 900}ms!`);
} else {
console.log(`INFO: ${path} ==> ${executionResponseTime}ms`);
}
return result;
};
// For the purposes of this example, we're going to add some random
// latency to each resolver. Please don't actually do this.
// Note: This is defined after the "logResponseTimeMiddleware" middleware,
// but we'll apply it before further down.
const addLatencyMiddleware = async (resolver, parent, args, context, info) => {
const executionStartTime = Date.now();
await new Promise((resolve) => {
setTimeout(resolve, Math.floor(Math.random() * (1000 - 250 + 1)) + 250);
});
return resolver(parent, args, { ...context, executionStartTime }, info);
};
// You've seen the rest before, so run `node index.js` (or `node .` if that's
// your jam).
const query = `
query GetMerchantTransactions($merchantId: ID!) {
merchant(id: $merchantId) {
id
name
transactions {
id
amount
date
}
}
}
`;
const schema = makeExecutableSchema({ typeDefs, resolvers });
const schemaWithMiddleware = applyMiddleware(schema, addLatencyMiddleware, logResponseTimeMiddleware);
(async () => {
const result = await graphql(schemaWithMiddleware, query, {}, { db }, { merchantId: 'CAYGCAYKAwYDBw8JBA8LDw' });
console.log(JSON.stringify(result, null, 2));
})();