Last active
February 26, 2017 21:40
-
-
Save du5rte/1f9ba167264033ac382aa5a2fc84321f to your computer and use it in GitHub Desktop.
GraphQL Subscriptions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component, PropTypes } from 'react'; | |
import { graphql } from 'react-apollo' | |
import gql from 'graphql-tag' | |
import update from 'immutability-helper' | |
import { Toggler, colors } from "./Toggler" | |
import View from "react-flexbox" | |
@graphql(gql` | |
query togglerQuery { | |
toggler | |
} | |
`) | |
@graphql(gql` | |
mutation togglerMutation($value: Boolean!) { | |
toggler(value: $value) | |
} | |
`,{ | |
props: ({ ownProps, mutate }) => ({ | |
toggle: (value) => mutate({ | |
variables: { | |
value | |
}, | |
updateQueries: { | |
togglerQuery: (prev, { mutationResult }) => update(prev, { | |
toggler: {$set: mutationResult.data.toggler} | |
}) | |
} | |
}) | |
}) | |
}) | |
export default class Render extends Component { | |
componentWillReceiveProps(newProps) { | |
if (!newProps.data.loading) { | |
if (this.subscription) { | |
if (newProps.data.feed !== this.props.data.feed) { | |
// if the feed has changed, we need to unsubscribe before resubscribing | |
this.subscription.unsubscribe(); | |
} else { | |
// we already have an active subscription with the right params | |
return; | |
} | |
} | |
// const entryIds = newProps.data.feed.map(item => item.id) | |
this.subscription = newProps.data.subscribeToMore({ | |
document: gql` | |
subscription togglerSubscription { | |
toggler | |
} | |
`, | |
variables: {}, | |
// this is where the magic happens. | |
updateQuery: (prev, {subscriptionData}) => { | |
console.log('😱') | |
return prev; // Modify your store and return new state with the new arrived data | |
}, | |
onError: (err) => console.error(err), | |
}) | |
} | |
} | |
handleToggle(e) { | |
this.props.toggle(!this.props.data.toggler) | |
.then(({ data }) => { | |
// this.props.data.refetch() | |
}).catch((error) => { | |
console.log(error) | |
}) | |
} | |
render() { | |
const style = { | |
justifyContent: 'center', | |
alignItems: 'center', | |
height: '100vh', | |
fontSize: '10vw', | |
background: this.props.data.toggler ? colors.green : colors.red, | |
} | |
return ( | |
<View style={style}> | |
<Toggler value={this.props.data.toggler} onClick={this.handleToggle.bind(this)} /> | |
</View> | |
) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
GraphQLBoolean, | |
GraphQLNonNull, | |
GraphQLObjectType | |
} from 'graphql' | |
let toggleValue = false | |
import { pubsub } from "../../subscriptionManager" | |
export const TogglerType = new GraphQLNonNull(GraphQLBoolean) | |
export const togglerQuery = { | |
type: TogglerType, | |
description: "0 or 1, false or true", | |
resolve(root, args, ctx, info) { | |
return toggleValue | |
} | |
} | |
export const togglerMutation = { | |
type: TogglerType, | |
description: "Perceptions of truth are relative, choose yours", | |
args: { | |
value: { | |
type: new GraphQLNonNull(GraphQLBoolean), | |
description: "0 or 1, false or true" | |
} | |
}, | |
resolve(root, args, ctx, info) { | |
return Promise.resolve() | |
.then(() => { | |
toggleValue = args.value | |
return toggleValue | |
}) | |
.then((value) => { | |
// publish subscription notification | |
pubsub.publish("togglerChannel", value) | |
return value | |
}) | |
} | |
} | |
const togglerSubscription = { | |
type: TogglerType, | |
description: "Are you ready for the truth?", | |
resolve(root, args, ctx, info) { | |
return sourceOfTruth | |
} | |
} | |
export default new GraphQLSchema({ | |
query: new GraphQLObjectType({ | |
name: 'Queries', | |
fields: () => ({ | |
togglerQuery | |
}) | |
}), | |
mutation: new GraphQLObjectType({ | |
name: 'Mutations', | |
fields: () => ({ | |
togglerMutation | |
}) | |
}), | |
subscription: new GraphQLObjectType({ | |
name: 'Subscriptions', | |
fields: () => ({ | |
togglerSubscription | |
}) | |
}) | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { SubscriptionManager, PubSub } from 'graphql-subscriptions' | |
import schema from "./schema" | |
const pubsub = new PubSub() | |
const subscriptionManager = new SubscriptionManager({ | |
schema, | |
pubsub, | |
setupFunctions: {}, | |
}) | |
pubsub.publish("togglerChannel", false) | |
pubsub.subscribe("togglerChannel", function(data){ | |
console.log(data) | |
}) | |
export { subscriptionManager, pubsub } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createServer } from 'http'; | |
import { SubscriptionServer } from 'subscriptions-transport-ws'; | |
import { subscriptionManager } from './subscriptionManager' | |
// start a subscription | |
subscriptionManager.subscribe({ | |
query: ` | |
subscription togglerSubscription { | |
toggler | |
} | |
`, | |
variables: {}, | |
context: {}, | |
callback: (err, data) => console.log(err, data), | |
}) | |
const WS_PORT = 5000; | |
// Create WebSocket listener server | |
const websocketServer = createServer((request, response) => { | |
response.writeHead(404); | |
response.end(); | |
}); | |
// Bind it to port and start listening | |
websocketServer.listen(WS_PORT, () => console.log( | |
`Websocket Server is now running on ws:${WS_PORT}` | |
)); | |
const subscriptionServer = new SubscriptionServer({ | |
onConnect: async (connectionParams) => { | |
// Implement if you need to handle and manage connection | |
console.log("connected") | |
}, | |
subscriptionManager: subscriptionManager | |
},{ | |
server: websocketServer, | |
path: '/' | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment