Skip to content

Commit

Permalink
Added subscriptions to graphql example
Browse files Browse the repository at this point in the history
  • Loading branch information
klis87 committed Feb 20, 2021
1 parent 27004e1 commit 156a270
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 7 deletions.
46 changes: 43 additions & 3 deletions examples/graphql/dev-server.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
require('@babel/polyfill');
const { createServer } = require('http');

const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const { ApolloServer, gql } = require('apollo-server-express');
const { ApolloServer, gql, PubSub } = require('apollo-server-express');

const webpackConfig = require('./webpack.config');

const pubsub = new PubSub();

const app = express();

app.use(
Expand All @@ -29,6 +33,8 @@ const books = [
},
];

let numberOfBookLikes = 0;

const typeDefs = gql`
type Book {
id: ID!
Expand All @@ -46,6 +52,7 @@ const typeDefs = gql`
type Query {
books: [Book!]!
book(id: ID!): Book
numberOfBookLikes: Int!
}
type Mutation {
Expand All @@ -55,14 +62,26 @@ const typeDefs = gql`
singleUpload(file: Upload!): File!
multipleUpload(files: [Upload!]!): [File!]!
}
type Subscription {
onBookLiked: Int!
}
`;

const findBookById = id => books.find(book => book.id === id);

const ON_BOOK_LIKED = 'ON_BOOK_LIKED';

const resolvers = {
Query: {
books: () => books,
book: (_, args) => findBookById(args.id),
numberOfBookLikes: () => numberOfBookLikes,
},
Subscription: {
onBookLiked: {
subscribe: () => pubsub.asyncIterator([ON_BOOK_LIKED]),
},
},
Mutation: {
deleteBook: (_, args) => findBookById(args.id),
Expand All @@ -74,6 +93,8 @@ const resolvers = {
}

book.liked = true;
numberOfBookLikes += 1;
pubsub.publish(ON_BOOK_LIKED, { onBookLiked: numberOfBookLikes });
return book;
},
unlikeBook: (_, args) => {
Expand All @@ -99,13 +120,32 @@ const resolvers = {
},
};

// const sleep = () => new Promise(resolve => setTimeout(resolve, 50));

const server = new ApolloServer({
typeDefs,
resolvers,
subscriptions: {
// onConnect: async connectionParams => {
// if (connectionParams.token === 'pass') {
// await sleep();

// return {
// currentUser: 'user',
// };
// }

// throw new Error('Missing auth token!');
// },
keepAlive: 10000,
},
});

server.applyMiddleware({ app });
server.applyMiddleware({ app, path: '/graphql' });

const httpServer = createServer(app);
server.installSubscriptionHandlers(httpServer);

app.listen(3000, () => {
httpServer.listen(3000, () => {
console.log('Listening on port 3000!');
});
30 changes: 28 additions & 2 deletions examples/graphql/src/components/app.jsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
import React from 'react';
import { useDispatch } from 'react-redux';
import { Query, Mutation } from '@redux-requests/react';
import { useDispatch, useSelector } from 'react-redux';
import { getWebsocketState } from '@redux-requests/core';
import {
Query,
Mutation,
useQuery,
useSubscription,
} from '@redux-requests/react';

import {
fetchNumberOfBookLikes,
fetchBooks,
fetchBook,
deleteBook,
likeBook,
unlikeBook,
uploadFile,
uploadFiles,
onBookLiked,
} from '../store/actions';
import {
FETCH_NUMBER_OF_BOOK_LIKES,
LIKE_BOOK,
UNLIKE_BOOK,
FETCH_BOOK,
FETCH_BOOKS,
UPLOAD_FILE,
UPLOAD_FILES,
ON_BOOK_LIKED,
} from '../store/constants';

import Spinner from './spinner';
Expand All @@ -30,10 +40,26 @@ const RequestError = () => (

const App = () => {
const dispatch = useDispatch();
const websocketState = useSelector(getWebsocketState);
const { data } = useQuery({
type: FETCH_NUMBER_OF_BOOK_LIKES,
action: fetchNumberOfBookLikes,
autoLoad: true,
});

useSubscription({
type: ON_BOOK_LIKED,
action: onBookLiked,
});

return (
<div>
<h1>Redux Requests GraphQL example</h1>
<div>
WS: {websocketState.connected ? 'connected' : 'disconnected'},{' '}
{websocketState.pristine ? 'pristine' : 'not pristine'}{' '}
</div>
{data && <div>Number of likes: {data.numberOfBookLikes}</div>}
<p>
In order to see aborts in action, you should set network throttling in
your browser
Expand Down
31 changes: 31 additions & 0 deletions examples/graphql/src/store/actions.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { gql } from '@redux-requests/graphql';

import {
FETCH_NUMBER_OF_BOOK_LIKES,
FETCH_BOOKS,
FETCH_BOOK,
DELETE_BOOK,
LIKE_BOOK,
UNLIKE_BOOK,
ON_BOOK_LIKED,
UPLOAD_FILE,
UPLOAD_FILES,
} from './constants';
Expand All @@ -18,6 +20,17 @@ const bookFragment = gql`
}
`;

export const fetchNumberOfBookLikes = () => ({
type: FETCH_NUMBER_OF_BOOK_LIKES,
request: {
query: gql`
{
numberOfBookLikes
}
`,
},
});

export const fetchBooks = () => ({
type: FETCH_BOOKS,
request: {
Expand Down Expand Up @@ -125,6 +138,24 @@ export const unlikeBook = id => ({
},
});

export const onBookLiked = () => ({
type: ON_BOOK_LIKED,
subscription: {
query: gql`
subscription {
onBookLiked
}
`,
},
meta: {
mutations: {
[FETCH_NUMBER_OF_BOOK_LIKES]: (data, subscriptionData) => ({
numberOfBookLikes: subscriptionData.onBookLiked,
}),
},
},
});

const fileFragment = gql`
fragment FileFragment on File {
filename
Expand Down
2 changes: 2 additions & 0 deletions examples/graphql/src/store/constants.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
export const FETCH_BOOKS = 'FETCH_BOOKS';
export const FETCH_BOOK = 'FETCH_BOOK';
export const FETCH_NUMBER_OF_BOOK_LIKES = 'FETCH_NUMBER_OF_BOOK_LIKES';
export const DELETE_BOOK = 'DELETE_BOOK';
export const LIKE_BOOK = 'LIKE_BOOK';
export const UNLIKE_BOOK = 'UNLIKE_BOOK';
export const UPLOAD_FILE = 'UPLOAD_FILE';
export const UPLOAD_FILES = 'UPLOAD_FILES';
export const ON_BOOK_LIKED = 'ON_BOOK_LIKED';
12 changes: 10 additions & 2 deletions examples/graphql/src/store/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import { createStore, applyMiddleware, combineReducers, compose } from 'redux';
import { handleRequests } from '@redux-requests/core';
import { createDriver } from '@redux-requests/graphql';
import { createDriver, createSubscriber } from '@redux-requests/graphql';

export const configureStore = () => {
const { requestsReducer, requestsMiddleware } = handleRequests({
driver: createDriver({ url: 'http://localhost:3000/graphql' }),
driver: createDriver({
url: 'http://localhost:3000/graphql',
}),
subscriber: createSubscriber({
url: 'ws://localhost:3000/graphql',
// lazy: false,
heartbeatTimeout: 12,
useHeartbeat: true,
}),
});

const reducers = combineReducers({
Expand Down

0 comments on commit 156a270

Please sign in to comment.