Gustavo Morales
@gmoralesc
// index.js
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello, World!\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});https://nodejs.org/en/about/
// app.js
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})https://expressjs.com/en/starter/hello-world.html
// app.js
const express = require('express');
const app = express();
app.get('/', (req, res) => res.end('Welcome API'));
app.get('/users', (req, res) => res.end('Users list'));
module.exports = app;no utilizamos el método listen de express
exportamos la instancia de la aplicación
// index.js
const http = require('http');
const app = require('./app');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer(app);
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});La instancia de express concuerda con el argumento de createServer
utilizamos el servidor http de Node.js
// index.js
// const express = require('express');
const express = require('./expresso');
const app = express();
app.get('/', (req, res) => res.end('Welcome API'));
app.get('/users', (req, res) => res.end('Users list'));
module.exports = app;La funcion de express es un constructor
Los metodos HTTP son funciones de la instancia
// expresso.js
module.exports = function expresso() {
const app = function app(req, res) {
};
app.get = (route, callback) => {
};
return app;
};Exportamos el constructor
Agregamos el método GET con un monkey patch a la función principal
Creamos la función principal
Incoming request
middleware
middleware
middleware
req, res
res.send()
next()
res.send()
404
GET /users
POST /users
// expresso.js
module.exports = function expresso() {
const middlewares = [];
const app = function app(req, res) {
};
app.get = (route, callback) => {
middlewares.push({
route,
callback,
method: 'GET',
});
};
return app;
};Creamos el Array de Middlewares
Registramos los callbacks al Array de middlewares
// expresso.js
const { parse } = require('url');
module.exports = function expresso() {
const middlewares = [];
const app = function app(req, res) {
// Extract URL
const { method, url } = req;
const { pathname } = parse(url);
// Match Route
let index = -1;
for (let i = 0; i < middlewares.length; i += 1) {
if (middlewares[i].route === pathname && middlewares[i].method === method) {
index = i;
break;
}
}
// Execute Callback
if (index === -1) {
res.statusCode = 404;
res.end('Not middleware Found');
} else {
middlewares[index].callback(req, res);
}
};
app.get = (route, callback) => {
middlewares.push({
route,
callback,
method: 'GET',
});
};
return app;
};Extraemos el pathname que la petición desea acceder
Buscamos si existe una función middleware que coincida
Devolvemos la respuesta adecuada
// index.js
// const express = require('express');
const express = require('./expresso');
const app = express();
app.get('/', (req, res) => res.send('Welcome API'));
app.get('/users', (req, res) => res.send('Users list'));
module.exports = app;Agregramos el método send
// expresso.js
const { parse } = require('url');
module.exports = function expresso() {
const middlewares = [];
function send(content) {
this.end(content);
}
const app = function app(req, res) {
res.send = send;
// Extract URL
const { method, url } = req;
const { pathname } = parse(url);
// Match Route
let index = -1;
for (let i = 0; i < middlewares.length; i += 1) {
if (middlewares[i].route === pathname && middlewares[i].method === method) {
index = i;
break;
}
}
// Execute Callback
if (index === -1) {
res.statusCode = 404;
res.end('Not middleware Found');
} else {
middlewares[index].callback(req, res);
}
};
app.get = (route, callback) => {
middlewares.push({
route,
callback,
method: 'GET',
});
};
return app;
};Agregamos la función send
Hacemos monkey patch, esta vez en el objeto de la respuesta
// index.js
// const express = require('express');
const express = require('./expresso');
const app = express();
app.get('/', (req, res) => res.send('Welcome API'));
app.get('/users', (req, res) => res.send('Users list'));
app.use((req, res) => {
res.statusCode = 404;
res.send('Route Not Found');
});
module.exports = app;Agregamos la opción para agregar middleware sin rutas
// expresso.js
const { parse } = require('url');
module.exports = function expresso() {
const middlewares = [];
function send(content) {
this.end(content);
}
const app = function app(req, res) {
res.send = send;
// Extract URL
const { method, url } = req;
const { pathname } = parse(url);
// Match Route
let index = -1;
for (let i = 0; i < middlewares.length; i += 1) {
if (middlewares[i].route) {
if (middlewares[i].route === pathname && middlewares[i].method === method) {
index = i;
break;
}
} else {
index = i;
break;
}
}
// Execute Callback
if (index === -1) {
res.statusCode = 404;
res.end('Not middleware Found');
} else {
middlewares[index].callback(req, res);
}
};
app.get = (route, callback) => {
middlewares.push({
route,
callback,
method: 'GET',
});
};
app.use = (callback) => {
middlewares.push({
callback,
});
};
return app;
};Agregamos el callback al Array de middlewares
// expresso.js
const { parse } = require('url');
module.exports = function expresso() {
const middlewares = [];
function send(content) {
this.end(content);
}
const app = function app(req, res) {
res.send = send;
// Extract URL
const { method, url } = req;
const { pathname } = parse(url);
// Match Route
let index = -1;
for (let i = 0; i < middlewares.length; i += 1) {
if (middlewares[i].route) {
if (middlewares[i].route === pathname && middlewares[i].method === method) {
index = i;
break;
}
} else {
index = i;
break;
}
}
// Execute Callback
if (index === -1) {
res.statusCode = 404;
res.end('Not middleware Found');
} else {
middlewares[index].callback(req, res);
}
};
app.get = (route, callback) => {
middlewares.push({
route,
callback,
method: 'GET',
});
};
app.use = (callback) => {
middlewares.push({
callback,
});
};
return app;
};Agregamos el nuevo caso cuando buscamos el middleware
// index.js
// const express = require('express');
const express = require('./expresso');
const app = express();
app.use((req, res, next) => {
const id = 123;
req.id = id;
next();
});
app.get('/', (req, res) => res.send('Welcome API'));
app.get('/users', (req, res) => {
const { id } = req;
res.send(`Userid: ${id}`));
}
app.use((req, res) => {
res.statusCode = 404;
res.send('Route Not Found');
});
module.exports = app;Agregamos el soporte para la función next
// expresso.js
const { parse } = require('url');
module.exports = function expresso() {
const middlewares = [];
function send(content) {
this.end(content);
}
const app = function next(req, res, start = 0) {
res.send = send;
// Extract URL
const { method, url } = req;
const { pathname } = parse(url);
// Match Route
let index = -1;
for (let i = start; i < middlewares.length; i += 1) {
if (middlewares[i].route) {
if (middlewares[i].route === pathname && middlewares[i].method === method) {
index = i;
break;
}
} else {
index = i;
break;
}
}
// Execute Callback
if (index === -1) {
res.statusCode = 404;
res.end('Not middleware Found');
} else {
middlewares[index].callback(req, res, () => {
next(req, res, index + 1);
});
}
};
app.get = (route, callback) => {
middlewares.push({
route,
callback,
method: 'GET',
});
};
app.use = (callback) => {
middlewares.push({
callback,
});
};
return app;
};Renombramos nuestra función principal
Agregamos el callback para continue con la busqueda si el usuario la invoca
// index.js
// const express = require('express');
const express = require('./expresso');
const app = express();
app.use((req, res, next) => {
const id = 123;
req.id = id;
next();
});
app.get('/', (req, res) => res.send('Welcome API'));
app.get('/users', (req, res) => {
const { id } = req;
res.json({
message: 'User',
id: req.id,
});
}
app.use((req, res) => {
res.status(404).json({
message: 'Route Not Found',
});
});
module.exports = app;Agregramos la función json
Agregamos la función status
// expresso.js
const { parse } = require('url');
module.exports = function expresso() {
const middlewares = [];
function send(content) {
this.end(content);
}
function json(content) {
this.setHeader('Content-Type', 'application/json');
this.end(JSON.stringify(content));
}
function status(code) {
this.statusCode = code;
return this;
}
const app = function next(req, res, start = 0) {
res.send = send;
res.json = json;
res.status = status;
// Extract URL
const { method, url } = req;
const { pathname } = parse(url);
// Match Route
let index = -1;
for (let i = start; i < middlewares.length; i += 1) {
if (middlewares[i].route) {
if (middlewares[i].route === pathname && middlewares[i].method === method) {
index = i;
break;
}
} else {
index = i;
break;
}
}
// Execute Callback
if (index === -1) {
res.statusCode = 404;
res.end('Not middleware Found');
} else {
middlewares[index].callback(req, res, () => {
next(req, res, index + 1);
});
}
};
app.get = (route, callback) => {
middlewares.push({
route,
callback,
method: 'GET',
});
};
app.use = (callback) => {
middlewares.push({
callback,
});
};
return app;
};Agregamos la función json
Agregamos la función status, retornando la misma instancia
Aplicamos el monkey patch al objeto de la respuesta
// index.js
// const express = require('express');
const express = require('./expresso');
const app = express();
app.use((req, res, next) => {
const id = 123;
req.id = id;
next();
});
app.get('/', (req, res) => res.send('Welcome API'));
app.get('/users', (req, res) => {
const { id } = req;
res.send(`Userid: ${id}`));
}
app.use((req, res) => {
res.statusCode = 404;
res.send('Route Not Found');
});
app.use((err, req, res, next) => {
const { message = '' } = err;
res.status(500).json({ message })
})
module.exports = app;Agregamos el middleware de error de express
// expresso.js
const { parse } = require('url');
module.exports = function expresso() {
const middlewares = [];
function send(content) {
this.end(content);
}
function json(content) {
this.setHeader('Content-Type', 'application/json');
this.end(JSON.stringify(content));
}
function status(code) {
this.statusCode = code;
return this;
}
const app = function next(req, res, start = 0, err = undefined) {
res.send = send;
res.json = json;
res.status = status;
// Extract URL
const { method, url } = req;
const { pathname } = parse(url);
// Match Route
let index = -1;
for (let i = start; i < middlewares.length; i += 1) {
if (err) {
if (middlewares[i].callback.length === 4) {
index = i;
break;
}
} else if (middlewares[i].route) {
if (middlewares[i].route === pathname && middlewares[i].method === method) {
index = i;
break;
}
} else {
index = i;
break;
}
}
// Execute Callback
if (index === -1) {
res.statusCode = 404;
res.end('Not middleware Found');
} else {
middlewares[index].callback(req, res, () => {
next(req, res, index + 1);
});
}
};
app.get = (route, callback) => {
middlewares.push({
route,
callback,
method: 'GET',
});
};
app.use = (callback) => {
middlewares.push({
callback,
});
};
return app;
};Modificamos nuevamente nuestro función principal
Agregamos el nuevo caso en la busqueda del middleware
// expresso.js
const { parse } = require('url');
module.exports = function expresso() {
const middlewares = [];
function send(content) {
this.end(content);
}
function json(content) {
this.setHeader('Content-Type', 'application/json');
this.end(JSON.stringify(content));
}
function status(code) {
this.statusCode = code;
return this;
}
const app = function next(req, res, start = 0, err = undefined) {
res.send = send;
res.json = json;
res.status = status;
// Extract URL
const { method, url } = req;
const { pathname } = parse(url);
// Match Route
let index = -1;
for (let i = start; i < middlewares.length; i += 1) {
if (err) {
if (middlewares[i].callback.length === 4) {
index = i;
break;
}
} else if (middlewares[i].route) {
if (middlewares[i].route === pathname && middlewares[i].method === method) {
index = i;
break;
}
} else {
index = i;
break;
}
}
// Execute Callback
if (index === -1) {
res.statusCode = 404;
res.end('Not middleware Found');
} else {
const params = [req, res];
if (err) {
params.unshift(err);
}
middlewares[index].callback(...params, (error = undefined) => {
next(req, res, index + 1, error);
});
}
};
app.get = (route, callback) => {
middlewares.push({
route,
callback,
method: 'GET',
});
};
app.use = (callback) => {
middlewares.push({
callback,
});
};
return app;
};Modificamos el orden de los parametros si es necesario para cumplir con la firma de express
Modificamos también nuestro callback
// index.js
// const express = require('express');
const express = require('./expresso');
const bodyParser = require('body-parser');
const app = express();
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));
// parse application/json
app.use(bodyParser.json());
app.use((req, res, next) => {
const id = 123;
req.id = id;
next();
});
app.get('/', (req, res) => res.send('Welcome API'));
app.post('/users', (req, res, next) => {
const { id } = req.body;
res.json({
id,
});
});
app.get('/users', (req, res) => {
const { id } = req;
res.send(`Userid: ${id}`));
}
app.use((req, res) => {
res.statusCode = 404;
res.send('Route Not Found');
});
app.use((err, req, res, next) => {
const { message = '' } = err;
res.status(500).json({ message })
})
module.exports = app;Agregamos body-parser para procesar los parametros
Agregamos el metodo POST
// expresso.js
const { parse } = require('url');
module.exports = function expresso() {
const middlewares = [];
function send(content) {
this.end(content);
}
function json(content) {
this.setHeader('Content-Type', 'application/json');
this.end(JSON.stringify(content));
}
function status(code) {
this.statusCode = code;
return this;
}
const app = function next(req, res, start = 0, err = undefined) {
res.send = send;
res.json = json;
res.status = status;
// Extract URL
const { method, url } = req;
const { pathname } = parse(url);
// Match Route
let index = -1;
for (let i = start; i < middlewares.length; i += 1) {
if (err) {
if (middlewares[i].callback.length === 4) {
index = i;
break;
}
} else if (middlewares[i].route) {
if (middlewares[i].route === pathname && middlewares[i].method === method) {
index = i;
break;
}
} else {
index = i;
break;
}
}
// Execute Callback
if (index === -1) {
res.statusCode = 404;
res.end('Not middleware Found');
} else {
const params = [req, res];
if (err) {
params.unshift(err);
}
middlewares[index].callback(...params, (error = undefined) => {
next(req, res, index + 1, error);
});
}
};
app.get = (route, callback) => {
middlewares.push({
route,
callback,
method: 'GET',
});
};
app.post = (route, callback) => {
middlewares.push({
route,
callback,
method: 'POST',
});
};
app.use = (callback) => {
middlewares.push({
callback,
});
};
return app;
};Agregamos soporte para el metodo POST
// index.js
// const express = require('express');
const express = require('./expresso');
const app = express();
app.use((req, res, next) => {
const id = 123;
req.id = id;
next();
});
app.get('/', (req, res) => res.send('Welcome API'));
app.get('/users', (req, res) => {
const { id } = req;
res.send(`Userid: ${id}`));
}
app.use((req, res) => {
res.statusCode = 404;
res.send('Route Not Found');
});
app.use((err, req, res, next) => {
const { message = '' } = err;
res.status(500).json({ message })
})
module.exports = app;Steve Jobs
Gracias