Skip to content

Commit

Permalink
[Add] 서버쪽 feed pubsub구현 #140
Browse files Browse the repository at this point in the history
why
새로운 글을 등록하면 구독자들에게 알려주고, 구독자들은 그 알람을 받아야 함

how
graphql의 pubsub을 활용해서 새로 등록된 글에 대한 알람이 오늘 것을 확인

주의
서버쪽 구현이며 아직 필터링은 되지 않음
  • Loading branch information
WooYeonSeo committed Dec 2, 2019
1 parent 325cfea commit f4ecf92
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 18 deletions.
4 changes: 4 additions & 0 deletions server/src/api/feed/feed.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,7 @@ type Mutation {
type Mutation {
enrollFeed(content: String!, files: [Upload]): Boolean!
}

type Subscription {
newFeed: [IFeed]
}
33 changes: 30 additions & 3 deletions server/src/api/feed/feed.resolvers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import db from '../../db';
import { MATCH_FEEDS, UPDATE_LIKE, DELETE_LIKE } from '../../schema/feed/query';
import {
MATCH_FEEDS,
UPDATE_LIKE,
DELETE_LIKE,
GET_NEW_FEED
} from '../../schema/feed/query';
import { ParseResultRecords } from '../../utils/parseData';
import {
MutationEnrollFeedArgs,
Expand Down Expand Up @@ -63,7 +68,7 @@ const mutationResolvers: MutationResolvers = {
enrollFeed: async (
_,
{ content, files }: MutationEnrollFeedArgs,
{ req }
{ req, pubsub }
): Promise<boolean> => {
const { email } = req;
if (!email) return false;
Expand All @@ -73,6 +78,18 @@ const mutationResolvers: MutationResolvers = {
if (files && files.length) {
createImages(feedId, files);
}

const registerdFeed = await requestDB(GET_NEW_FEED, {
feedId,
useremail: email
});
// console.log('registerdFeed?? ', registerdFeed);
const parsedRegisterdFeed = ParseResultRecords(registerdFeed);
// console.log('parsedRegisterdFeed?? ', parsedRegisterdFeed);

pubsub.publish(NEW_FEED, {
newFeed: parsedRegisterdFeed
});
return true;
},
updateLike: async (_, { feedId, count }, { req }) => {
Expand Down Expand Up @@ -112,7 +129,17 @@ const queryResolvers: QueryResolvers = {
}
};

const NEW_FEED = 'NEW_FEED_PUBSUB';

export default {
Query: queryResolvers,
Mutation: mutationResolvers
Mutation: mutationResolvers,
Subscription: {
newFeed: {
subscribe: (_, __, { pubsub }) => {
console.log('subscripbed');
return pubsub.asyncIterator(NEW_FEED);
}
}
}
};
9 changes: 7 additions & 2 deletions server/src/app.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import cookieParser from 'cookie-parser';
import cors from 'cors';
import { GraphQLServer } from 'graphql-yoga';
import { GraphQLServer, PubSub } from 'graphql-yoga';
import helmet from 'helmet';
import logger from 'morgan';
import config from './utils/config';
Expand All @@ -12,9 +12,14 @@ import setUserFromJWT from './middleware/setUserFromJWT';
class App {
public app: GraphQLServer;
constructor() {
const pubsub = new PubSub();
this.app = new GraphQLServer({
schema,
context: ({ request, response }) => ({ req: request, res: response })
context: ({ request, response }) => ({
req: request,
res: response,
pubsub
})
});
this.middlewares();
}
Expand Down
24 changes: 12 additions & 12 deletions server/src/schema/feed/query.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,3 @@
/* const MATCH_FEEDS1 = `MATCH (searchUser:User)-[:AUTHOR]->(feed:Feed)
OPTIONAL MATCH (likeUser:User)-[:LIKE]->(feed)
OPTIONAL MATCH (feed)-[:HAS]->(com:Comment)
WITH searchUser, feed, COLLECT(DISTINCT likeUser) AS cp , COLLECT(com) as comments
where feed.createdAt < datetime({cursor})
RETURN searchUser , feed, ID(feed) as feedId , length(cp) AS totallikes,
length(filter(x IN cp WHERE x.email= {useremail} )) AS hasLiked, comments
order by feed.createdAt desc
LIMIT {first}
`; */

const MATCH_FEEDS = `MATCH (searchUser:User)-[:AUTHOR]->(feed:Feed)
OPTIONAL MATCH (likeUser:User)-[like:LIKE]->(feed)
OPTIONAL MATCH (feed)-[:HAS]->(com:Comment)
Expand All @@ -32,4 +21,15 @@ MATCH (u:User)-[r:LIKE]->(f:Feed)
WHERE u.email = {useremail} AND ID(f) = {feedId}
delete r`;

export { MATCH_FEEDS, UPDATE_LIKE, DELETE_LIKE };
const GET_NEW_FEED = `MATCH (searchUser:User)-[:AUTHOR]->(feed:Feed)
OPTIONAL MATCH (likeUser:User)-[like:LIKE]->(feed)
OPTIONAL MATCH (feed)-[:HAS]->(com:Comment)
OPTIONAL MATCH (feed)<-[:HAS]-(img:Image)
WITH searchUser, feed, COLLECT(DISTINCT likeUser) AS cp , COLLECT(com) as comments, COLLECT(DISTINCT img) as imgs
where ID(feed) = {feedId}
RETURN searchUser , feed, ID(feed) as feedId , length(cp) AS totallikes, imgs as imglist,
length(filter(x IN cp WHERE x.email= {useremail} )) AS hasLiked, comments
order by feed.createdAt desc
`;

export { MATCH_FEEDS, UPDATE_LIKE, DELETE_LIKE, GET_NEW_FEED };
5 changes: 4 additions & 1 deletion server/src/utils/parseData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ export const Datetransform = object => {
}
return returnobj;
};

/**
* 주의사항 : 결과가 여러개이면 result.records 한개이면 result를 record로 받아야 함
* @param records
*/
export const ParseResultRecords = records => {
let result: any[] = [];
for (const item of records) {
Expand Down

0 comments on commit f4ecf92

Please sign in to comment.