154 lines
3.1 KiB
JavaScript
154 lines
3.1 KiB
JavaScript
const express = require('express')
|
|
const cors = require('cors')
|
|
const { gql, ApolloServer, ApolloError, PubSub, withFilter } = require('apollo-server-express')
|
|
const shortid = require('shortid')
|
|
|
|
const typeDefs = gql`
|
|
type Channel {
|
|
id: ID!
|
|
label: String!
|
|
messages: [Message!]!
|
|
}
|
|
|
|
type Message {
|
|
id: ID!
|
|
channel: Channel!
|
|
text: String!
|
|
}
|
|
|
|
type Query {
|
|
hello: String!
|
|
channels: [Channel!]!
|
|
channel (id: ID!): Channel
|
|
list: [String!]!
|
|
good: String
|
|
bad: String
|
|
}
|
|
|
|
type Mutation {
|
|
addMessage (input: AddMessageInput!): Message
|
|
updateMessage (input: UpdateMessageInput!): Message
|
|
}
|
|
|
|
input AddMessageInput {
|
|
channelId: ID!
|
|
text: String!
|
|
}
|
|
|
|
input UpdateMessageInput {
|
|
id: ID!
|
|
channelId: ID!
|
|
text: String!
|
|
}
|
|
|
|
type Subscription {
|
|
messageAdded (channelId: ID!): Message!
|
|
messageUpdated (channelId: ID!): Message!
|
|
}
|
|
`
|
|
|
|
const pubsub = new PubSub()
|
|
|
|
let channels = []
|
|
|
|
function resetDatabase () {
|
|
channels = [
|
|
{
|
|
id: 'general',
|
|
label: 'General',
|
|
messages: [],
|
|
},
|
|
{
|
|
id: 'random',
|
|
label: 'Random',
|
|
messages: [],
|
|
},
|
|
]
|
|
}
|
|
|
|
resetDatabase()
|
|
|
|
const resolvers = {
|
|
Query: {
|
|
hello: () => 'Hello world!',
|
|
channels: () => channels,
|
|
channel: (root, { id }) => channels.find(c => c.id === id),
|
|
list: () => ['a', 'b', 'c'],
|
|
good: () => 'good',
|
|
bad: () => {
|
|
throw new Error('An error')
|
|
},
|
|
},
|
|
|
|
Mutation: {
|
|
addMessage: (root, { input }) => {
|
|
const channel = channels.find(c => c.id === input.channelId)
|
|
if (!channel) {
|
|
throw new ApolloError(`Channel ${input.channelId} not found`, 'not-found')
|
|
}
|
|
const message = {
|
|
id: shortid(),
|
|
channel: channel,
|
|
text: input.text,
|
|
}
|
|
channel.messages.push(message)
|
|
pubsub.publish('messageAdded', { messageAdded: message })
|
|
return message
|
|
},
|
|
|
|
updateMessage: (root, { input }) => {
|
|
const channel = channels.find(c => c.id === input.channelId)
|
|
if (!channel) {
|
|
throw new ApolloError(`Channel ${input.channelId} not found`, 'not-found')
|
|
}
|
|
const message = channel.messages.find(m => m.id === input.id)
|
|
Object.assign(message, {
|
|
text: input.text,
|
|
})
|
|
pubsub.publish('messageUpdated', { messageUpdated: message })
|
|
return message
|
|
},
|
|
},
|
|
|
|
Subscription: {
|
|
messageAdded: {
|
|
subscribe: withFilter(
|
|
() => pubsub.asyncIterator('messageAdded'),
|
|
(payload, variables) => payload.messageAdded.channel.id === variables.channelId,
|
|
),
|
|
},
|
|
|
|
messageUpdated: {
|
|
subscribe: withFilter(
|
|
() => pubsub.asyncIterator('messageUpdated'),
|
|
(payload, variables) => payload.messageUpdated.channel.id === variables.channelId,
|
|
),
|
|
},
|
|
},
|
|
}
|
|
|
|
const app = express()
|
|
|
|
app.use(cors('*'))
|
|
|
|
app.get('/_reset', (req, res) => {
|
|
resetDatabase()
|
|
res.status(200).end()
|
|
})
|
|
|
|
const server = new ApolloServer({
|
|
typeDefs,
|
|
resolvers,
|
|
context: () => new Promise(resolve => {
|
|
setTimeout(() => resolve({}), 50)
|
|
}),
|
|
})
|
|
|
|
server.applyMiddleware({ app })
|
|
|
|
app.listen({
|
|
port: 4042,
|
|
}, () => {
|
|
console.log('🚀 Server ready at http://localhost:4042')
|
|
})
|