'use strict'
const http = require('http')
const Request = require('./Request')
const Response = require('./Response')
/**
* Represents the server
*/
class Server {
/**
* Creates a server
* @param {object} params
* @param {number} params.port - HTTP Port
*/
constructor (params) {
const { port } = params
this._port = port
this._server = http.createServer()
this._routes = {
default: ({ method, url }, response) => {
return response
.setStatusCode(404)
.send(`Route ${method} for ${url} not found`)
}
}
this._server.on('request', (httpRequest, httpResponse) => {
const data = []
httpRequest
.on('data', chunk => data.push(chunk))
.on('end', () => {
const { headers, method, url } = httpRequest
let body = Buffer.concat(data).toString()
if (headers['content-type'] === 'application/json') body = JSON.parse(body)
const request = new Request({ ...httpRequest, body })
const response = new Response(httpResponse)
if (this._routes[url] && this._routes[url][method]) {
this._routes[url][method](request, response)
} else {
this._routes.default(request, response)
}
})
})
}
/**
* Appends a new route using the method GET
* @param {string} url - Request URL
* @param {function} callback - Request handler
*/
get (url, callback) {
this._routes[url] = {
...this._routes[url],
GET: callback
}
}
/**
* Appends a new route using the method POST
* @param {string} url - Request URL
* @param {function} callback - Request handler
*/
post (url, callback) {
this._routes[url] = {
...this._routes[url],
POST: callback
}
}
/**
* Appends a new route using the method PATCH
* @param {string} url - Request URL
* @param {function} callback - Request handler
*/
patch (url, callback) {
this._routes[url] = {
...this._routes[url],
PATCH: callback
}
}
/**
* Appends a new route using the method PUT
* @param {string} url - Request URL
* @param {function} callback - Request handler
*/
put (url, callback) {
this._routes[url] = {
...this._routes[url],
PUT: callback
}
}
/**
* Appends a new route using the method DELETE
* @param {string} url - Request URL
* @param {function} callback - Request handler
*/
delete (url, callback) {
this._routes[url] = {
...this._routes[url],
DELETE: callback
}
}
/**
* Starts the server
* @returns {Promise}
*/
start () {
return new Promise((resolve, _reject) => {
this._server.listen(this._port, () => {
resolve()
})
})
}
}
module.exports = Server