Skip to content

Commit bc2954c

Browse files
committed
feat(init): 初始化demo
0 parents  commit bc2954c

17 files changed

+2002
-0
lines changed

Diff for: .gitignore

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
6+
# Runtime data
7+
pids
8+
*.pid
9+
*.seed
10+
*.pid.lock
11+
12+
# Directory for instrumented libs generated by jscoverage/JSCover
13+
lib-cov
14+
15+
# Coverage directory used by tools like istanbul
16+
coverage
17+
18+
# nyc test coverage
19+
.nyc_output
20+
node_modules/
21+
22+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
23+
.grunt
24+
npm-debug.log
25+
26+
# node-waf configuration
27+
.lock-wscript
28+
29+
# Compiled binary addons (http://nodejs.org/api/addons.html)
30+
build/Release
31+
32+
# Dependency directories
33+
node_modules
34+
jspm_packages
35+
36+
# Optional npm cache directory
37+
.npm
38+
39+
# Optional eslint cache
40+
.eslintcache
41+
42+
# Optional REPL history
43+
.node_repl_history
44+
45+
# Output of 'npm pack'
46+
*.tgz
47+
48+
# Yarn Integrity file
49+
.yarn-integrity
50+
51+
webpack-assets.json
52+
webpack-stats.json
53+
54+
# editor
55+
.idea/
56+
.vscode
57+
58+
# eslint
59+
.DS_Store
60+
61+
# session
62+
sessions
63+
64+
# dist directory
65+
static/dist
66+
docs/swagger-html
67+
src/server/requests
68+
src/server/mock-controllers
69+
docs/swagger.yaml
70+
docs/html/spec-files/swagger.yaml
71+
src/server/swagger/definitions.js
72+
.javadoc/
73+
74+
#.bak
75+
*.bak
76+
77+
# maven
78+
~/

Diff for: README.md

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
## demo介绍
2+
该demo是学习graphql基础的,里面包含了使用基础包graphql-js实现功能,以及apollo-graphql实现功能,以及使用apollo-graphql实现发布订阅功能
3+
4+
## 项目技术栈
5+
6+
1. 使用create-react-app创建前端代码
7+
8+
1.1 使用apollo全家桶完善一个带有TODO功能的页面
9+
10+
1.2 使用RR4带有路由功能
11+
12+
1.3 未使用的功能有:graphql的缓存功能、mock数据的功能、性能的测试
13+
14+
2. 使用apollo-server-express启动服务器
15+
16+
2.1 使用MongoDB做数据库存储
17+
18+
2.2 支持数据修改通知功能
19+
20+
2.3 有playgroundf功能,可以辅助测试接口
21+
22+
2.4 不具备完整的线上运行要求,只推荐在本地调试使用
23+
24+
25+
## 项目启动
26+
27+
graphql-js: `node express-graphql.js`
28+
29+
apollo-graphql(不带订阅功能): `node apollo-graphql.js`
30+
31+
apollo-graphql(带订阅功能):
32+
33+
```
34+
cd client && npm install && npm run build
35+
cd server && node apollo-graphql-pubsub.js
36+
37+
```
38+
39+
## 基础知识
40+
41+
为了看懂这3个demo,可以参考我的系列文章:
42+
43+
1. []()
44+
45+
46+
2. []()

Diff for: apollo-graphql.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
const express = require('express');
2+
const { ApolloServer, gql } = require('apollo-server-express');
3+
4+
// Construct a schema, using GraphQL schema language
5+
const typeDefs = gql`
6+
type Query {
7+
hello: String
8+
}
9+
`;
10+
11+
// Provide resolver functions for your schema fields
12+
const resolvers = {
13+
Query: {
14+
hello: () => 'Hello world!',
15+
},
16+
};
17+
18+
const server = new ApolloServer({ typeDefs, resolvers });
19+
20+
const app = express();
21+
server.applyMiddleware({ app });
22+
23+
app.listen({ port: 4000 }, () =>
24+
console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`)
25+
);

Diff for: client

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit c0ecc6563f33d2c76d38bb7042e062eaa37bc787

Diff for: express-graphql.js

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
const express = require('express');
2+
const graphqlHTTP = require('express-graphql');
3+
const { buildSchema } = require('graphql');
4+
5+
const fakeDatabase = [];
6+
7+
// Construct a schema, using GraphQL schema language
8+
const schema = buildSchema(`
9+
input MessageInput {
10+
content: String
11+
author: String
12+
}
13+
14+
type Message {
15+
id: ID!
16+
content: String
17+
author: String
18+
}
19+
type Query {
20+
getMessage(id: ID): [Message]
21+
}
22+
type Mutation {
23+
createMessage(input: MessageInput): Message
24+
updateMessage(id: ID!, input: MessageInput): Message
25+
}
26+
`);
27+
28+
// The root provides a resolver function for each API endpoint
29+
const root = {
30+
getMessage: ({id}) => {
31+
console.log(id)
32+
if (!id) {
33+
return fakeDatabase
34+
}
35+
if (!fakeDatabase[id]) {
36+
throw new Error('no message exists with id ' + id);
37+
}
38+
return [fakeDatabase[id]]
39+
},
40+
createMessage: function ({input}) {
41+
// Create a random id for our "database".
42+
var id = require('crypto').randomBytes(10).toString('hex')
43+
fakeDatabase.push({ id, ...input });
44+
45+
return fakeDatabase[fakeDatabase.length - 1]
46+
},
47+
updateMessage: function({id, input}) {
48+
if (!fakeDatabase[id]) {
49+
throw new Error('no message exists with id ' + id);
50+
}
51+
const newInput = { ...fakeDatabase[id], ...input }
52+
// This replaces all old data, but some apps might want partial update.
53+
fakeDatabase[id] = newInput;
54+
return newInput
55+
}
56+
};
57+
58+
const app = express();
59+
app.use('/graphql', graphqlHTTP({
60+
schema: schema,
61+
rootValue: root,
62+
graphiql: true,
63+
}));
64+
app.listen(4000);
65+
console.log('Running a GraphQL API server at localhost:4000/graphql');

Diff for: package.json

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"name": "graphql-todo-demo",
3+
"version": "1.0.0",
4+
"description": "graphql todo demo with graphql-js & apollo-graphql",
5+
"main": "index.js",
6+
"scripts": {
7+
"start": ""
8+
},
9+
"keywords": [
10+
"graphql",
11+
"express",
12+
"apollo-graphql"
13+
],
14+
"author": "[email protected]",
15+
"license": "MIT",
16+
"dependencies": {
17+
"apollo-server-express": "^2.4.8",
18+
"body-parser": "^1.18.3",
19+
"express": "^4.14.1",
20+
"express-graphql": "^0.7.1",
21+
"graphql": "^14.1.1",
22+
"graphql-subscriptions": "^1.0.0",
23+
"graphql-tools": "^4.0.4",
24+
"merge-graphql-schemas": "^1.5.8",
25+
"mongoose": "^5.4.19",
26+
"mongoose-unique-validator": "^2.0.2",
27+
"ramda": "^0.26.1",
28+
"react-apollo": "^2.5.3",
29+
"subscriptions-transport-ws": "^0.9.16",
30+
"uuid": "^3.3.2"
31+
}
32+
}

Diff for: process.json

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"apps": [{
3+
"name": "test",
4+
"script": "io.js",
5+
"cwd": "/Users/linxiaowu/Github/nodejs-rtc-demo",
6+
"instances": 6,
7+
"exec_mode": "cluster",
8+
"watch": false,
9+
"env_production": {
10+
"NODE_ENV": "production"
11+
},
12+
"log_date_format": "DD-MM-YYYY HH:MM:ss"
13+
}]
14+
}

Diff for: public/index.html

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!doctype html>
2+
<html lang="en" data-framework="relay">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1">
6+
<title>GraphQL • TodoMVC</title>
7+
</head>
8+
<body>
9+
<div id="root"></div>
10+
</body>
11+
</html>

Diff for: server/apollo-config.js

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const {
2+
ApolloServer
3+
} = require('apollo-server-express')
4+
const {
5+
PubSub,
6+
} = require('graphql-subscriptions')
7+
const R = require('ramda')
8+
const { schema } = require('./graphql')
9+
const { todolist } = require('./models/TodoList')
10+
11+
const CLIENT_ID = 'linxiaowu66-client-id'
12+
13+
const server = new ApolloServer({
14+
schema,
15+
context({
16+
req
17+
}) {
18+
return {
19+
models: { todolist },
20+
clientID: R.path(['headers', CLIENT_ID])(req),
21+
}
22+
},
23+
playground: {
24+
endpoint: '/graphql',
25+
settings: {
26+
'editor.theme': 'light'
27+
},
28+
subscriptionEndpoint: 'ws://localhost:4000/subscriptions'
29+
}
30+
})
31+
32+
exports.server = server

Diff for: server/apollo-graphql-pubsub.js

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
const mongo = require('mongoose')
2+
const path = require('path')
3+
const { createServer } = require('http')
4+
const { SubscriptionServer } = require('subscriptions-transport-ws')
5+
const express = require('express');
6+
const { execute, subscribe } = require('graphql');
7+
const { server } = require('./apollo-config')
8+
const { schema } = require('./graphql')
9+
require('./env')
10+
11+
const app = express()
12+
13+
server.applyMiddleware({ app })
14+
15+
app.use(express.static(path.join(__dirname, '../client/build'), { maxAge: 86400000 }));
16+
17+
// Create webSocketServer
18+
const ws = createServer(app)
19+
20+
// Configure params for mongoConnection
21+
const options = { useNewUrlParser: true, useCreateIndex: true, useFindAndModify: false }
22+
23+
mongo.connect(process.env.URI, options).then(() => {
24+
// If connected, then start server
25+
26+
ws.listen(process.env.PORT, () => {
27+
console.log('Server on port', process.env.PORT)
28+
console.log('Mongo on port: ', process.env.DBPORT)
29+
30+
// Set up the WebSocket for handling GraphQL subscriptions
31+
new SubscriptionServer({
32+
execute,
33+
subscribe,
34+
schema
35+
}, {
36+
server: ws,
37+
path: '/subscriptions',
38+
});
39+
});
40+
41+
}).catch(err => {
42+
console.log(err)
43+
})

Diff for: server/env.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
process.env.PORT = process.env.PORT || 4000 // Port express
2+
3+
// Configuration MongoDB
4+
process.env.DBNAME = process.env.DBNAME || 'graphql-demo';
5+
process.env.DBHOST = process.env.DBHOST || 'localhost';
6+
process.env.DBUSER = process.env.DBUSER || 'user';
7+
process.env.DBPASS = process.env.DBPASS || '';
8+
process.env.DBPORT = process.env.DBPORT || 27017;
9+
10+
// For development
11+
process.env.URI = `mongodb://${process.env.DBHOST}:${process.env.DBPORT}/${process.env.DBNAME}`;

Diff for: server/graphql/index.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const { makeExecutableSchema } = require('graphql-tools')
2+
const { fileLoader, mergeResolvers, mergeTypes } = require('merge-graphql-schemas')
3+
const path = require('path')
4+
5+
const resolversArray = fileLoader(path.join(__dirname, './resolvers/'), { recursive: true, extensions: ['.js'] });
6+
const typesArray = fileLoader(path.join(__dirname, './types/'), { recursive: true, extensions: ['.gql'] });
7+
const resolvers = mergeResolvers(resolversArray);
8+
const typeDefs = mergeTypes(typesArray, {all: true});
9+
const schema = makeExecutableSchema({ typeDefs, resolvers });
10+
11+
exports.schema = schema

0 commit comments

Comments
 (0)