Skip to content

Instantly share code, notes, and snippets.

@alex-taxiera
Last active March 26, 2020 05:08
Show Gist options
  • Save alex-taxiera/781cb5bfbaf6c9a4f66f9accad102386 to your computer and use it in GitHub Desktop.
Save alex-taxiera/781cb5bfbaf6c9a4f66f9accad102386 to your computer and use it in GitHub Desktop.
Simple example of server side events with express in TypeScript
import express, { RequestHandler, Response } from 'express'
import bodyParser from 'body-parser'
import cors from 'cors'
interface Client {
id: string
res: Response
}
interface Item {
id: string
name: string
}
const app = express()
const itemMiddleware = (): RequestHandler => {
const clientCount = 0
const clients: Array<Client> = []
const items: Array<Item> = []
return (_, res, next): void => {
res.locals.clientCount = clientCount
res.locals.clients = clients
res.locals.items = items
next()
}
}
app.use(cors())
app.use(bodyParser.json({}))
app.use(itemMiddleware())
app.get('/', (req, res) => {
res.json({ message: 'it works' })
})
app.post('/item', (req, res) => {
const {
id,
name
} = req.body
if (res.locals.items.find((item: Item) => item.id === id)) {
res.status(400).json({
message: `Item ${id} already exists`
})
return
}
const item: Item = {
id,
name
}
res.locals.items.push(item)
res.locals.clients.forEach(
(client: Client) => client.res.write(`data: ${JSON.stringify(item)}\n\n`)
)
res.json({
message: 'OK',
data: item
})
})
app.get('/item', (req, res) => {
res.json({
message: 'OK',
data: res.locals.items
})
})
app.get('/item/feed', (req, res) => {
res.setHeader('Cache-Control', 'no-cache')
res.setHeader('Content-Type', 'text/event-stream')
res.setHeader('Connection', 'keep-alive')
res.flushHeaders()
res.write('\n\n')
const client: Client = {
id: (++res.locals.clientCount).toString(),
res
}
res.locals.clients.push(client)
req.on('close', () => {
res.locals.clients = res.locals.clients
.filter((c: Client) => c.id !== client.id)
})
})
app.get('/item/:id', (req, res) => {
const {
id
} = req.params
const item = res.locals.items.find((item: Item) => item.id === id)
if (item) {
res.json({
message: 'OK',
data: item
})
} else {
res.status(404).json({ message: 'Not OK' })
}
})
app.listen(3030, () => console.log('listening')) // eslint-disable-line
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment