Last active
January 19, 2021 11:13
-
-
Save heygema/ffe70894153b209e5b642bb0ab60cfdf to your computer and use it in GitHub Desktop.
chat server gql
This file contains hidden or 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 path from 'path'; | |
import express from 'express'; | |
import http from 'http'; | |
import {ApolloServer, gql} from 'apollo-server-express'; | |
import makeIO from 'socket.io'; | |
import prisma from './prismaClient'; | |
const typeDefs = gql` | |
type Query { | |
hello(name: String): String! | |
messages(roomId: String!): [String!]! | |
friends(email: String!): [Friendship!]! | |
users: [User!]! | |
} | |
type User { | |
id: String! | |
email: String! | |
name: String! | |
} | |
type Friendship { | |
id: String! | |
friendshipType: FriendshipType! | |
users: [User!]! | |
} | |
enum FriendshipType { | |
Friend | |
Group | |
} | |
type Mutation { | |
createUser(email: String, name: String): User | |
} | |
`; | |
const resolvers = { | |
Query: { | |
hello: (_: any, {name}: any) => { | |
return `hello ${name}`; | |
}, | |
users: () => { | |
return prisma.user.findMany(); | |
}, | |
friends: async (_: any, {email}: {email: string}) => { | |
let friends = await prisma.friendship.findMany({ | |
where: { | |
friendshipType: 'Friend', | |
users: { | |
some: {email}, | |
}, | |
}, | |
include: { | |
users: { | |
where: { | |
NOT: { | |
email, | |
}, | |
}, | |
}, | |
}, | |
}); | |
return friends; | |
}, | |
messages: async (_: any, {roomId}: {roomId: string}) => { | |
let friendship = await prisma.friendship.findUnique({ | |
where: { | |
id: roomId, | |
}, | |
include: { | |
messages: { | |
include: { | |
sender: {}, | |
}, | |
}, | |
}, | |
}); | |
return friendship?.messages; | |
}, | |
}, | |
Mutation: { | |
createUser: async ( | |
_: any, | |
{email, name}: {email: string; name: string} | |
) => { | |
let result = await prisma.user.create({ | |
data: { | |
email, | |
name, | |
}, | |
}); | |
return result; | |
}, | |
}, | |
}; | |
const apolloServer = new ApolloServer({ | |
typeDefs, | |
resolvers, | |
context: (contexts) => ({ | |
...contexts, | |
prisma, | |
}), | |
}); | |
let app = express(); | |
app.set('prisma', prisma); | |
app.use(express.static(path.join(__dirname, '../public'))); | |
apolloServer.applyMiddleware({app}); | |
let server = http.createServer(app); | |
// @ts-ignore | |
const io = makeIO(server); | |
io.on('connection', (socket: any) => { | |
console.log(`someone ${socket.id} in`); | |
socket.on('join-friend-room', (roomId: number) => { | |
socket.join(roomId); | |
socket.emit('message', `Welcome ${socket.id}`); | |
}); | |
type MessageFromUser = { | |
senderId: string; | |
roomId: string; | |
content: string; | |
}; | |
// for security purpose, get sender id from cached roomId on connectedsocket | |
socket.on( | |
'message-from-client', | |
async ({senderId, roomId, content}: MessageFromUser) => { | |
// persist to db here | |
let message = await prisma.message.create({ | |
data: { | |
friendship: { | |
connect: { | |
id: roomId, | |
}, | |
}, | |
sender: { | |
connect: { | |
id: senderId, | |
}, | |
}, | |
content, | |
}, | |
}); | |
io.to(roomId).emit('message-from-server', message); | |
} | |
); | |
}); | |
server.listen(4000, () => { | |
console.log(`Server running on http://localhost${4000}`); | |
}); |
This file contains hidden or 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
// This is your Prisma schema file, | |
// learn more about it in the docs: https://pris.ly/d/prisma-schema | |
datasource db { | |
provider = "postgresql" | |
url = env("DATABASE_URL") | |
} | |
generator client { | |
provider = "prisma-client-js" | |
} | |
model User { | |
id String @id @default(cuid()) | |
email String @unique | |
name String? | |
friendships Friendship[] | |
messages Message[] | |
createdAt DateTime @default(now()) @map(name: "created_at") | |
@@map(name: "users") | |
} | |
model Friendship { | |
id String @id @default(cuid()) | |
users User[] | |
friendshipType FriendshipType | |
messages Message[] | |
createdAt DateTime @default(now()) @map(name: "created_at") | |
@@map(name: "friendships") | |
} | |
enum FriendshipType { | |
Group | |
Friend | |
} | |
model Message { | |
id String @id @default(cuid()) | |
friendship Friendship @relation(fields: [friendshipId], references: [id]) | |
sender User @relation(fields: [userId], references: [id]) | |
friendshipId String | |
userId String | |
content String | |
createdAt DateTime @default(now()) @map(name: "created_at") | |
@@map(name: "messages") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment