2020-10-16 18:43:15 +02:00

122 lines
2.5 KiB
JavaScript

const { gql, ApolloServer, ApolloError, PubSub, withFilter } = require('apollo-server')
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 {
channels: [Channel!]!
channel (id: ID!): Channel
}
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()
const channels = [
{
id: 'general',
label: 'General',
messages: [],
},
{
id: 'random',
label: 'Random',
messages: [],
},
]
const resolvers = {
Query: {
channels: () => channels,
channel: (root, { id }) => channels.find(c => c.id === id),
},
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 server = new ApolloServer({
typeDefs,
resolvers,
})
server.listen({
port: 4042,
}).then(({ url }) => {
console.log(`🚀 Server ready at ${url}`)
})