Skip to content

Commit e0d09e8

Browse files
authored
Final chapter seven (MoonHighway#8)
* Adds Photo Uploads * Ignores jpg photos * Minor code changes * Completes Chapter 7 Photo Share Exercise * adds mock server
1 parent 4088bb6 commit e0d09e8

18 files changed

Lines changed: 290 additions & 26 deletions

File tree

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ package-lock.json
1212

1313
.DS_Store
1414

15+
*.jpg
1516

1617
# Runtime data
1718
pids
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const { ApolloServer, MockList } = require('apollo-server')
2+
const { readFileSync } = require('fs')
3+
4+
const typeDefs = readFileSync('./typeDefs.graphql', 'UTF-8')
5+
const resolvers = {}
6+
7+
const mocks = {
8+
Query: () => ({
9+
totalPhotos: () => 42,
10+
allPhotos: () => new MockList([5, 10]),
11+
Photo: () => ({
12+
name: 'sample photo',
13+
description: null
14+
})
15+
})
16+
}
17+
18+
const server = new ApolloServer({
19+
typeDefs,
20+
resolvers,
21+
mocks
22+
})
23+
24+
server.listen({ port: 4000 }, () =>
25+
console.log(`Mock Photo Share GraphQL Service`)
26+
)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"scripts": {
3+
"start": "nodemon ."
4+
},
5+
"dependencies": {
6+
"apollo-server": "^2.0.0-rc.5",
7+
"graphql": "^0.13.2"
8+
},
9+
"devDependencies": {
10+
"nodemon": "^1.18.1"
11+
}
12+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
scalar DateTime
2+
3+
type User {
4+
githubLogin: ID!
5+
name: String
6+
avatar: String
7+
postedPhotos: [Photo!]!
8+
inPhotos: [Photo!]!
9+
}
10+
11+
type Photo {
12+
id: ID!
13+
name: String!
14+
url: String!
15+
description: String
16+
category: PhotoCategory!
17+
postedBy: User!
18+
taggedUsers: [User!]!
19+
created: DateTime!
20+
}
21+
22+
enum PhotoCategory {
23+
SELFIE
24+
PORTRAIT
25+
ACTION
26+
LANDSCAPE
27+
GRAPHIC
28+
}
29+
30+
input PostPhotoInput {
31+
name: String!
32+
category: PhotoCategory = PORTRAIT
33+
description: String
34+
file: Upload!
35+
}
36+
37+
type AuthPayload {
38+
token: String!
39+
user: User!
40+
}
41+
42+
type Query {
43+
me: User
44+
totalPhotos: Int!
45+
allPhotos: [Photo!]!
46+
Photo(id: ID!): Photo
47+
totalUsers: Int!
48+
allUsers: [User!]!
49+
User(login: ID!): User
50+
}
51+
52+
type Mutation {
53+
postPhoto(input: PostPhotoInput!): Photo!
54+
tagPhoto(githubLogin:ID! photoID:ID!): Photo!
55+
githubAuth(code: String!): AuthPayload!
56+
addFakeUsers(count: Int=1): [User!]!
57+
fakeUserAuth(githubLogin: ID!): AuthPayload!
58+
}
59+
60+
type Subscription {
61+
newPhoto: Photo!
62+
newUser: User!
63+
}

‎chapter-07/photo-share-api/.env‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
DB_HOST=mongodb://localhost:27017/photo-share
2-
CLIENT_ID=deba4977ddbd7ceee828
3-
CLIENT_SECRET=6d1a5ae588cbb9778420a36b9b9ec23f3649d5b2
4-
APOLLO_ENGINE_KEY=service:MoonTahoe-2777:zt4iq0miRB-l3Q94yLrsOw
1+
DB_HOST=<YOUR MONGO DB URL>
2+
CLIENT_ID=<YOUR GITHUB CLIENT ID>
3+
CLIENT_SECRET=<YOUR GITHUB CLIENT SECRET>
4+
ENGINE_API_KEY=<YOUR APOLLO ENGINE API KEY>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Photos Folder
2+
=============
3+
All uploaded photos will be saved to this folder.

‎chapter-07/photo-share-api/index.js‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ const { MongoClient } = require('mongodb')
55
const { readFileSync } = require('fs')
66
const expressPlayground = require('graphql-playground-middleware-express').default
77
const resolvers = require('./resolvers')
8+
const path = require('path')
9+
const depthLimit = require('graphql-depth-limit')
10+
const { createComplexityLimitRule } = require('graphql-validation-complexity')
811

912
require('dotenv').config()
1013
var typeDefs = readFileSync('./typeDefs.graphql', 'UTF-8')
@@ -33,6 +36,13 @@ async function start() {
3336
const server = new ApolloServer({
3437
typeDefs,
3538
resolvers,
39+
engine: true,
40+
validationRules: [
41+
depthLimit(5),
42+
createComplexityLimitRule(1000, {
43+
onCost: cost => console.log('query cost: ', cost)
44+
})
45+
],
3646
context: async ({ req, connection }) => {
3747
const githubToken = req ? req.headers.authorization : connection.context.Authorization
3848
const currentUser = await db.collection('users').findOne({ githubToken })
@@ -49,8 +59,14 @@ async function start() {
4959
res.end(`<a href="${url}">Sign In with Github</a>`)
5060
})
5161

62+
app.use(
63+
'/img/photos',
64+
express.static(path.join(__dirname, 'assets', 'photos'))
65+
)
66+
5267
const httpServer = createServer(app)
5368
server.installSubscriptionHandlers(httpServer)
69+
httpServer.timeout = 5000
5470

5571
httpServer.listen({ port: 4000 }, () =>
5672
console.log(`GraphQL Server running at http://localhost:4000${server.graphqlPath}`)

‎chapter-07/photo-share-api/lib.js‎

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const authorizeWithGithub = async credentials => {
3131
return { ...githubUser, access_token }
3232
}
3333

34-
const saveFile = (stream, path) =>
34+
const uploadStream = (stream, path) =>
3535
new Promise((resolve, reject) => {
3636
stream.on('error', error => {
3737
if (stream.truncated) {
@@ -42,9 +42,4 @@ const saveFile = (stream, path) =>
4242
.pipe(fs.createWriteStream(path))
4343
})
4444

45-
const uploadFile = async (file, path) => {
46-
const { stream } = await file
47-
return saveFile(stream, path)
48-
}
49-
50-
module.exports = {findBy, authorizeWithGithub, generateFakeUsers, uploadFile}
45+
module.exports = {findBy, authorizeWithGithub, generateFakeUsers, uploadStream}

‎chapter-07/photo-share-api/package.json‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
"dotenv": "^6.0.0",
1515
"express": "^4.16.3",
1616
"graphql": "^0.13.2",
17+
"graphql-depth-limit": "^1.1.0",
1718
"graphql-playground-middleware-express": "^1.7.1",
19+
"graphql-validation-complexity": "^0.2.3",
1820
"mongodb": "^3.1.0",
1921
"node-fetch": "^2.1.2"
2022
},

‎chapter-07/photo-share-api/resolvers/Mutation.js‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
const { authorizeWithGithub } = require('../lib')
22
const fetch = require('node-fetch')
33
const { ObjectID } = require('mongodb')
4+
const { uploadStream } = require('../lib')
5+
const path = require('path')
46

57
module.exports = {
68

@@ -19,6 +21,11 @@ module.exports = {
1921
const { insertedIds } = await db.collection('photos').insert(newPhoto)
2022
newPhoto.id = insertedIds[0]
2123

24+
var toPath = path.join(__dirname, '..', 'assets', 'photos', `${newPhoto.id}.jpg`)
25+
26+
const { stream } = await args.input.file
27+
await uploadStream(stream, toPath)
28+
2229
pubsub.publish('photo-added', { newPhoto })
2330

2431
return newPhoto

0 commit comments

Comments
 (0)