Skip to content

Instantly share code, notes, and snippets.

@Eomm
Created November 13, 2022 09:49
Show Gist options
  • Save Eomm/dc87ed70cc7ac3ad2a03eff8e98ba983 to your computer and use it in GitHub Desktop.
Save Eomm/dc87ed70cc7ac3ad2a03eff8e98ba983 to your computer and use it in GitHub Desktop.
Add dynamic routes to Fastify
// a quick check to implement a dynamic route plugin for fastify
const { fastify } = require('fastify')
const fp = require('fastify-plugin')
const http = require('http')
const EventEmitter = require('events')
main()
async function main () {
let app = fastify()
app.register(fp(async function plugin (instance, opts) {
const ee = new EventEmitter()
ee.on('replace', opts.rootInstanceReplacer)
instance.decorate('dynamicPost', async function () {
const replace = fastify(instance.initialConfig)
// todo get all the plugins/addSchema/addHook from the original instance
// how to preserve the encapsulation?
replace.post(...arguments)
await replace.ready()
app.server.removeListener('request', app.routing)
replace.server = app.server
replace.server.on('request', replace.routing)
// todo app.dispose()
// - close connections or copy the children?
// - fastify builder application or clone the children?
// - adds a new recreate method to the fastify instance?
ee.emit('replace', replace)
return replace
})
}), {
rootInstanceReplacer: (newFastify) => { app = newFastify }
})
app.get('/', async (request, reply) => {
console.log('GET /')
await app.dynamicPost('/', () => {
console.log('post')
return { hello: 'world' }
})
return ''
})
console.log('listening')
// await app.listen(8080)
// { const res = await httpCall('http://localhost:8080/', 'GET')
// console.log(res.statusCode)
// }
// { const res = await httpCall('http://localhost:8080/', 'POST')
// console.log(res.statusCode) }
// await app.close()
await app.ready()
{ const res = await app.inject('/')
console.log(res.statusCode)
}
{ const res = await app.inject({ method: 'POST', url: '/' })
console.log(res.statusCode) }
}
function httpCall (url, method, body) {
return new Promise((resolve, reject) => {
const req = http.request(url, { method }, res => {
let data = ''
res.on('data', chunk => { data += chunk })
res.on('end', () => {
resolve({ statusCode: res.statusCode, data })
})
})
req.on('error', reject)
req.end(body)
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment