Skip to content

Instantly share code, notes, and snippets.

@DanielFL0
Last active November 4, 2022 04:39
Show Gist options
  • Save DanielFL0/b5555dbd2dd7d78898dcee4344b27120 to your computer and use it in GitHub Desktop.
Save DanielFL0/b5555dbd2dd7d78898dcee4344b27120 to your computer and use it in GitHub Desktop.
Create a simple node.js backend framework
import http from 'http'
function App () {
this.plugins = []
}
App.prototype.use = function (middleware) {
this.plugins.push(middleware)
}
App.prototype.handle = function (req, res, callback) {
let idx = 0
const next = () => {
if (idx >= this.plugins.length) {
return setImmediate(() => callback())
}
const layer = this.plugins[idx++]
setImmediate(() => {
layer(req, res, next)
})
}
next()
}
App.prototype.listen = function (port) {
const handler = (req, res) => {
return this.handle(req, res, () => {})
}
return http.createServer(handler).listen({ port })
}
export { App }
function Logger (format) {
this.format = format || ':method ":url"'
}
Logger.prototype.log = function (req, res) {
const str = this.format
.replace(':method', req.method)
.replace(':url', req.url)
console.log(str)
}
export { Logger }
import { Router } from './router.js'
import { Logger } from './logger.js'
import { App } from './app.js'
const logger = new Logger()
const router = new Router()
const app = new App()
app.use((req, res, next) => {
logger.log(req, res)
next()
})
router.get('/favicon.ico', (req, res) => {
res.writeHead(200, {'Content-Type': 'image/x-icon'})
res.end()
})
router.get('/static/index.css', (req, res) => {
res.writeHead(200, {'Content-Type': 'text/stylesheet'})
res.end()
})
router.use('GET', '/home', (req, res) => {
res.writeHead(200, {'Content-Type': 'text/html'})
res.write('home page')
res.end()
})
router.use('GET', '/posts', (req, res) => {
res.writeHead(200, {'Content-Type': 'text/html'})
res.write('posts page')
res.end()
})
app.use((req, res, next) => {
router.route(req, res)
next()
})
const server = app.listen(3000)
import http from 'http'
function Router () {
this.routes = {}
http.METHODS.forEach((method) => {
this.routes[method] = {}
})
}
Router.prototype.use = function (method, url, callback) {
this.routes[method][url] = callback
}
Router.prototype.get = function (url, callback) {
this.use('GET', url, callback)
}
Router.prototype.post = function (url, callback) {
this.use('POST', url, callback)
}
Router.prototype.put = function (url, callback) {
this.use('PUT', url, callback)
}
Router.prototype.delete = function (url, callback) {
this.use('DELETE', url, callback)
}
Router.prototype.route = function (req, res) {
const callback = this.routes[req.method][req.url]
callback(req, res)
}
export { Router }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment