Skip to content

Commit 1a55fbd

Browse files
committed
add basic query and mutation
0 parents  commit 1a55fbd

File tree

16 files changed

+2719
-0
lines changed

16 files changed

+2719
-0
lines changed

Diff for: .babelrc

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"presets": [
3+
[
4+
"env",
5+
{
6+
"targets": {
7+
"node": "current"
8+
}
9+
}
10+
]
11+
]
12+
}

Diff for: .gitignore

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# Created by .ignore support plugin (hsz.mobi)
2+
### JetBrains template
3+
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
4+
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
5+
6+
# User-specific stuff:
7+
.idea/**/workspace.xml
8+
.idea/**/tasks.xml
9+
.idea/dictionaries
10+
11+
# Sensitive or high-churn files:
12+
.idea/**/dataSources/
13+
.idea/**/dataSources.ids
14+
.idea/**/dataSources.xml
15+
.idea/**/dataSources.local.xml
16+
.idea/**/sqlDataSources.xml
17+
.idea/**/dynamic.xml
18+
.idea/**/uiDesigner.xml
19+
20+
# Gradle:
21+
.idea/**/gradle.xml
22+
.idea/**/libraries
23+
24+
# CMake
25+
cmake-build-debug/
26+
cmake-build-release/
27+
28+
# Mongo Explorer plugin:
29+
.idea/**/mongoSettings.xml
30+
31+
## File-based project format:
32+
*.iws
33+
34+
## Plugin-specific files:
35+
36+
# IntelliJ
37+
out/
38+
39+
# mpeltonen/sbt-idea plugin
40+
.idea_modules/
41+
42+
# JIRA plugin
43+
atlassian-ide-plugin.xml
44+
45+
# Cursive Clojure plugin
46+
.idea/replstate.xml
47+
48+
# Crashlytics plugin (for Android Studio and IntelliJ)
49+
com_crashlytics_export_strings.xml
50+
crashlytics.properties
51+
crashlytics-build.properties
52+
fabric.properties
53+
### Node template
54+
# Logs
55+
logs
56+
*.log
57+
npm-debug.log*
58+
yarn-debug.log*
59+
yarn-error.log*
60+
61+
# Runtime data
62+
pids
63+
*.pid
64+
*.seed
65+
*.pid.lock
66+
67+
# Directory for instrumented libs generated by jscoverage/JSCover
68+
lib-cov
69+
70+
# Coverage directory used by tools like istanbul
71+
coverage
72+
73+
# nyc test coverage
74+
.nyc_output
75+
76+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
77+
.grunt
78+
79+
# Bower dependency directory (https://bower.io/)
80+
bower_components
81+
82+
# node-waf configuration
83+
.lock-wscript
84+
85+
# Compiled binary addons (https://nodejs.org/api/addons.html)
86+
build/Release
87+
88+
# Dependency directories
89+
node_modules/
90+
jspm_packages/
91+
92+
# Typescript v1 declaration files
93+
typings/
94+
95+
# Optional npm cache directory
96+
.npm
97+
98+
# Optional eslint cache
99+
.eslintcache
100+
101+
# Optional REPL history
102+
.node_repl_history
103+
104+
# Output of 'npm pack'
105+
*.tgz
106+
107+
# Yarn Integrity file
108+
.yarn-integrity
109+
110+
# dotenv environment variables file
111+
.env
112+
113+
# next.js build output
114+
.next
115+

Diff for: app.js

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import express from 'express';
2+
import expressGraphQL from 'express-graphql';
3+
import morgan from 'morgan';
4+
5+
import client from './data/redis';
6+
import schema from './data/schema';
7+
8+
const logger = morgan('dev');
9+
10+
const app = express();
11+
app.use(logger);
12+
13+
app.use('/graphql', expressGraphQL({
14+
schema: schema,
15+
graphiql: true,
16+
context: {
17+
client
18+
},
19+
pretty: true
20+
}));
21+
22+
export default app;

Diff for: bin/www

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import debug from 'debug';
2+
import http from 'http';
3+
import app from '../app';
4+
import redis from '../data/redis';
5+
6+
const logger = debug('redis-pubsub:server');
7+
const port = normalizePort(process.env.PORT || '3000');
8+
app.set('port', port);
9+
const server = http.createServer(app);
10+
11+
redis
12+
.connect(() => logger("Redis connected"))
13+
.then(() => {
14+
server.listen(port);
15+
server.on('error', onError);
16+
server.on('listening', onListening);
17+
})
18+
.catch(err => console.error(err.stack));
19+
20+
/**
21+
* Normalize a port into a number, string, or false.
22+
*/
23+
24+
function normalizePort(val) {
25+
const port = parseInt(val, 10);
26+
27+
if (isNaN(port)) {
28+
// named pipe
29+
return val;
30+
}
31+
32+
if (port >= 0) {
33+
// port number
34+
return port;
35+
}
36+
37+
return false;
38+
}
39+
40+
/**
41+
* Event listener for HTTP server "error" event.
42+
*/
43+
44+
function onError(error) {
45+
if (error.syscall !== 'listen') {
46+
throw error;
47+
}
48+
49+
const bind = typeof port === 'string'
50+
? 'Pipe ' + port
51+
: 'Port ' + port;
52+
53+
// handle specific listen errors with friendly messages
54+
switch (error.code) {
55+
case 'EACCES':
56+
console.error(bind + ' requires elevated privileges');
57+
process.exit(1);
58+
break;
59+
case 'EADDRINUSE':
60+
console.error(bind + ' is already in use');
61+
process.exit(1);
62+
break;
63+
default:
64+
throw error;
65+
}
66+
}
67+
68+
/**
69+
* Event listener for HTTP server "listening" event.
70+
*/
71+
72+
function onListening() {
73+
const addr = server.address();
74+
const bind = typeof addr === 'string'
75+
? 'pipe ' + addr
76+
: 'port ' + addr.port;
77+
logger('Listening on ' + bind);
78+
}

Diff for: data/models/dish.js

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import {GraphQLError} from 'graphql';
2+
3+
export default function (ctx) {
4+
const {client} = ctx;
5+
6+
function set(v) {
7+
return client.set('dish', JSON.stringify(v)).then((result) => {
8+
if (result === 'OK') {
9+
return v;
10+
} else {
11+
return new GraphQLError('failed to store data into redis: ' + result);
12+
}
13+
});
14+
}
15+
16+
function get() {
17+
return client.get('dish')
18+
.then(v => JSON.parse(v))
19+
.catch(err => new GraphQLError('failed to get data from redis: ' + err));
20+
}
21+
22+
return {
23+
get,
24+
set
25+
}
26+
}

Diff for: data/models/index.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import dish from './dish';
2+
3+
export {
4+
dish
5+
};

Diff for: data/mutations/dish.js

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import {GraphQLNonNull, GraphQLString} from 'graphql';
2+
import {dish as DishModel} from '../models'
3+
import {dish as DishType} from '../type';
4+
5+
const dishField = {
6+
type: DishType,
7+
args: {
8+
name: {
9+
type: new GraphQLNonNull(GraphQLString),
10+
description: 'the name of a dish',
11+
}
12+
},
13+
resolve(source, {name}, context, info) {
14+
const dish = {
15+
id: Math.random().toString(34).slice(2),
16+
name
17+
};
18+
return DishModel(context).set(dish);
19+
}
20+
};
21+
22+
export default dishField;

Diff for: data/mutations/index.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import {GraphQLObjectType,} from 'graphql';
2+
import dish from './dish';
3+
4+
export default new GraphQLObjectType({
5+
name: 'Mutation',
6+
description: 'root mutation',
7+
fields: {
8+
updateDish: dish
9+
}
10+
});

Diff for: data/queries/dish.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import {dish as DishModel} from '../models'
2+
import {dish as DishType} from '../type';
3+
4+
const dishField = {
5+
type: DishType,
6+
resolve(source, args, context, info) {
7+
return DishModel(context).get();
8+
}
9+
};
10+
11+
export default dishField;

Diff for: data/queries/index.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import {GraphQLObjectType} from 'graphql';
2+
import dish from './dish';
3+
4+
export default new GraphQLObjectType({
5+
name: 'Query',
6+
description: 'root query',
7+
fields: {
8+
dish
9+
}
10+
})

Diff for: data/redis.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import Redis from 'ioredis';
2+
3+
export default new Redis({
4+
lazyConnect: true
5+
});

Diff for: data/schema.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import {GraphQLSchema} from 'graphql';
2+
import query from './queries';
3+
import mutation from './mutations';
4+
5+
export default new GraphQLSchema({
6+
query,
7+
mutation,
8+
})

Diff for: data/type/dish.js

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import {GraphQLID, GraphQLNonNull, GraphQLObjectType, GraphQLString} from 'graphql';
2+
3+
export default new GraphQLObjectType({
4+
name: 'Dish',
5+
description: 'a dish is **delicious** dish',
6+
fields: {
7+
id: {
8+
type: new GraphQLNonNull(GraphQLID),
9+
},
10+
name: {
11+
type: new GraphQLNonNull(GraphQLString),
12+
}
13+
}
14+
})

Diff for: data/type/index.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import dish from './dish';
2+
3+
export {
4+
dish
5+
};

Diff for: package.json

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"name": "graphql-redis-pubsub-demo",
3+
"version": "0.0.1",
4+
"main": "index.js",
5+
"author": "Jonir Rings <[email protected]>",
6+
"license": "MIT",
7+
"dependencies": {
8+
"express": "^4.16.2",
9+
"express-graphql": "^0.6.11",
10+
"graphiql": "^0.11.11",
11+
"graphql": "^0.11.0",
12+
"graphql-redis-subscriptions": "^1.4.0",
13+
"graphql-relay": "^0.5.4",
14+
"graphql-subscriptions": "^0.5.6",
15+
"ioredis": "^3.2.2",
16+
"prop-types": "^15.6.0",
17+
"react": "^16.2.0",
18+
"react-dom": "^16.2.0",
19+
"subscriptions-transport-ws": "^0.9.5"
20+
},
21+
"devDependencies": {
22+
"babel-cli": "^6.26.0",
23+
"babel-preset-env": "^1.6.1",
24+
"debug": "^3.1.0",
25+
"morgan": "^1.9.0"
26+
},
27+
"scripts": {
28+
"start": "babel-node ./bin/www"
29+
}
30+
}

0 commit comments

Comments
 (0)