-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
126 lines (113 loc) · 3.09 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
/**
* Lesson 11 - Comment count
*
* If we want to count the comments for each post, the simplest way is to reuse
* our existing comment loader and simply grab the length of the array that it returns
*
* Lets add that to the schema, returning an Int, and then test the query out
*
* Getting a few zeroes and a 5, so the count is being returned correctly
*
* If we are always going query both "commentCount" and the list of "comments" at the same time,
* the DataLoader will batch them together and we essentially get the count for free
* with no extra database requests
*/
const { ApolloServer, gql } = require('apollo-server')
const DataLoader = require('dataloader');
const sql = require('knex')({
client: 'pg',
connection: {
host : '127.0.0.1',
port : 5432,
user : 'postgres',
password : 'password',
database : 'postgres'
}
});
// A schema is a collection of type definitions (hence "typeDefs")
// that together define the "shape" of queries that are executed against
// your data.
const typeDefs = gql`
type Query {
posts: [Post]
post(id: String): Post
}
type Post {
id: String
title: String
author: User
comments: [Comment]
commentCount: Int
}
type User {
id: String
name: String
}
type Comment {
id: String
text: String
author: User
}
`
const resolvers = {
Query: {
posts() {
// Executes once per query
console.log('SELECT * from posts')
return sql('posts').select('*')
},
post(parent, { id }, { postLoader }) {
// Executes once per query
return postLoader.load(id)
}
},
Post: {
async author(post, args, { userLoader }) {
// Executes once per post per query
return userLoader.load(post.author_id)
},
async comments(post, args, { commentsByPostIdLoader }) {
// Executes once per post per query
return commentsByPostIdLoader.load(post.id)
},
async commentCount(post, args, { commentsByPostIdLoader }) {
return commentsByPostIdLoader
.load(post.id)
.then(comments => comments.length)
}
},
Comment: {
async author(post, args, { userLoader }) {
// Executes once per comment per post per query
return userLoader.load(post.author_id)
},
}
}
const server = new ApolloServer({
typeDefs,
resolvers,
async context() {
return {
userLoader: new DataLoader(keys => sql
.select('*')
.from('users')
.whereIn('id', keys)
),
postLoader: new DataLoader(keys => sql
.select('*')
.from('posts')
.whereIn('id', keys)
),
commentsByPostIdLoader: new DataLoader(postIds => sql
.select('*')
.from('comments')
.whereIn('post_id', postIds)
.then(comments => postIds.map(postId => comments.filter(comment => comment.post_id === postId)))
)
}
}
})
// The `listen` method launches a web server.
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
})