Use the express.Router class to create modular, mountable route handlers. A Router instance is a complete middleware and routing system; for this reason, it is often referred to as a “mini-app”.
var express = require('express')
var app = express()
var users = [];
app.get('/', function (req, res) {
res.json(users);
})
app.get('/:id', function (req, res) {
const id = req.params.id;
const user = users.find(u => u.id == id);
return res.json(user)
})
app.listen(5000)
server.js
const express = require('express');
const app = express();
app.use(express.json());
const usersRouter = require('./api/users');
app.use('/api/users', usersRouter);
app.listen(5000);
server.js
var router = require('express').Router()
var users = [];
router.get('/', function (req, res) {
res.json(users);
})
router.get('/:id', function (req, res) {
const id = +req.params.id;
const user = users.find(u => u.id === id);
return res.send(user)
})
module.exports = router
/api/users/index.js
const express = require('express');
const app = express();
// Resources routers
const usersRouter = require('./api/users');
// Applying middlewares and routes
app.use(express.json());
app.use('/api/users', usersRouter);
app.listen(5000);
var axios = require('axios');
var cheerio = require('cheerio');
...
module.exports = {
getHTML : useAxiosToExtractDOM,
extractInfo : parseDOMToDataUsingCheerio
}
function useAxiosToExtractDOM(url) { }
function parseDOMToDataUsingCheerio(html) { }
utils/extractor.js
var app = require('express')();
var extractor = require('./utils/extractor');
app.get('/extractInfo', (req, res) => {
const url = req.queryParams.url;
extractor.getHTML(url)
.then(extractor.extracInfo)
.then( data => res.json(data))
}
server.js
var axios = require('axios');
var cheerio = require('cheerio');
...
module.exports = {
getHTML : useAxiosToExtractDOM,
extractInfo : parseDOMToDataUsingCheerio
}
const router = require('express').Router();
router.get('/', ( req, res) => {
// Code here
});
router.get('/:id', ( req, res) => {
// Code here
});
router.post('/', ( req, res) => {
// Code here
});
module.exports = router;
api/users/index.js
const express = require('express');
const app = express();
// Resources routers
const usersRouter = require('./api/users');
app.use('/api/users', usersRouter);
server.js
const router = require('express').Router();
router.get('/', ( req, res) => {
// Code here
});
router.get('/:id', ( req, res) => {
// Code here
});
router.post('/', ( req, res) => {
// Code here
});
module.exports = router;
api/users/index.js
const router = require('express').Router();
const magic = require('./whereTheMagicHappens');
router.get('/', magic.doWhatever);
router.get('/:id', magic.doWhatever);
router.post('/', magic.doWhatever);
module.exports = router;
/api/users/index.js
index.js 10 líneas
api/users/index.js 8 líneas
api/users/users.controller.js 60 líneas
Queremos desarrollar una api restful con node para un proyecto copia de twitter. Aunque de momento, será solo una primera versión con usuarios y tweets como si fuese un blog personal.
USUARIOS
username* : string<uniq>
name? : string
email* : string
tweetsIDs : string[]
TWEETS
id* : string<uniq>
text : string
owner : string<ID>
createdAt : timestamp
Esto sería un id de los tweets que este usuario había creado
"2 tablas"
OJO ! CONTROLA QUE LA API NO SE PUEDA QUEDAR PILLADA EN NINGÚN MOMENTO, controla campos vacíos, request inválidas, etc etc y devuelve el error en la respuesta y el código correcto para dicho caso
Esta vez, no en ficheros, sino en una base de datos
¿ WHY MONGO?
Base de datos basada en documentos
Nos permite guardar la información como si de un objeto se tratase.
Los documentos del mismo tipo no están obligados a tener unos campos si o si e incluso estos podrán variar
EJEMPLO
Ejecutamos en una terminal
mongod o la ruta completa al .exe
y nos dirá que está listo y escuchando en el puerto 27017
Para acceder a la consola de mongo una vez tengamos el mongod corriendo debemos de ejecutar el comando/ejecutable mongo
Hay módulos que nos permiten interacturar con los Documentos y collecciones de nuestra base de datos como si de objetos y arrays normales se tratasen :O
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/todolist');
var TODOschema = mongoose.Schema({
text: String,
id : String,
createdAt : Number,
isCompleted : Boolean
});
var TODO = mongoose.model('todo', TODOschema);
TODO.find({}, (err, res) => {
console.log(res);
})
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/todolist');
var TODOschema = mongoose.Schema({
text: String,
id : String,
createdAt : Number,
isCompleted : Boolean
});
var TODO = mongoose.model('todo', TODOschema);
TODO.find({}, (err, res) => {
console.log(res);
})
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/todolist');
var TODOschema = mongoose.Schema({
text: String,
id : String,
createdAt : Number,
isCompleted : Boolean
});
var TODO = mongoose.model('todo', TODOschema);
TODO.find({}, (err, res) => {
console.log(res);
})
var TODO = mongoose.model('todo', TODOschema);
TODO.find({})
TODO.find({createdAt : 1521713274870})
TODO.find({createdAt : { $gt : 1521713274870} })
TODO.find({ otros : { $in : [ {hola : "mundo" } ]} })
// Proyecciones
TODO.find({createdAt : 1521713274870}, "text createdAt" )
Person.
find({
occupation: /host/,
'name.last': 'Ghost',
age: { $gt: 17, $lt: 66 },
likes: { $in: ['vaporizing', 'talking'] }
})
.limit(10)
.sort({ occupation: -1 })
.select({ name: 1, occupation: 1 })
.exec(callback);
// Using query builder
Person.
find({ occupation: /host/ })
.where('name.last').equals('Ghost')
.where('age').gt(17).lt(66)
.where('likes').in(['vaporizing', 'talking'])
.limit(10)
.sort('-occupation')
.select('name occupation')
.exec(callback);
var TODO = mongoose.model('todo', TODOschema);
var nuevo = new TODO({
text : 'Hello',
id : "asd",
createdAt : 13131312313,
isCompleted : false
})
nuevo.save();
Insertando documentos
TODO.create({ text: 'hola' }, function (err, small) {
if (err) return res.status(500).json(err);
// saved!
});
TODO.create({ text: 'hola' }).then(doc) {
// confirmed
});
Insertando documentos
TODO.create({ text: 'hola' }).then(doc) {
// confirmed
});
var TODO = mongoose.model('todo', TODOschema);
TODO.findOne ( { "text" : "hola" } , (err , doc) => {
doc.text = 'Nuevo texto';
doc.save();
}
Actualizando documentos
var TODO = mongoose.model('todo', TODOschema);
TODO.findOne ( { "text" : "hola" })
.update( { "text" : "adios" } )
.exec()
var TODO = mongoose.model('todo', TODOschema);
TODO.findOne ( { "text" : "hola" } , (err , doc) => {
doc.remove();
}
Borrando documentos
var TODO = mongoose.model('todo', TODOschema);
TODO.findOne( { "text" : "hola" })
.remove()
Borrando documentos
const TODOModel = require('./todos.model');
function getAllTODOs(req, res) {
TODOModel.find()
.then(response => {
console.log(response);
res.json(response);
})
}
Fichero : /api/todos/todos.controller.js
const TODOModel = require('./todos.model');
function getTODOById(req, res) {
TODOModel.findOne({ id : req.params.id})
.then(response => {
res.json(response);
})
}
Fichero : /api/todos/todos.controller.js
const TODOModel = require('./todos.model');
function getTODOById(req, res) {
TODOModel.findById(req.params.id)
.then(response => {
res.json(response);
})
.catch(err => {
res.json(err);
})
}
Fichero : /api/todos/todos.controller.js
SI USAMOS LOS _ID de mongo quedaría así
async function resumenDeTodo( req, res ){
// Buscar por el ID
const encontrado = await model.findById(req.params.id)
// Insertar nuevos
const insertado = await model.create(req.body)
// Buscar por algún campo
const encontrados = await model.find({ name : req.params.name})
// Borrar por el ID
const borradoPorId = await model.findByIdAndRemove(req.params.id)
// Encontrar y editar por el ID
const borradoPorNombre = await model.findByIdAndUpdate(req.params.id , req.body)
}
También son promesas
A currar
Guarda tus datos del proyecto de todolist en mongodb y usa mongoose para conectar tu api con la base de datos. NO HAGAS VALIDACIONES
const mongoose = require('mongoose');
var TODOschema = mongoose.Schema({
text: String,
id: String,
createdAt: Number,
isCompleted: Boolean
});
var TODO = mongoose.model('todo', TODOschema);
module.exports = TODO;
var breakfastSchema = new Schema({
eggs: {
type: Number,
min: [6, 'Too few eggs'],
max: 12
},
bacon: {
type: Number,
required: [true, 'Why no bacon?']
},
drink: {
type: String,
enum: ['Coffee', 'Tea'],
required: function() {
return this.bacon > 3;
}
}
});
var Breakfast = db.model('Breakfast', breakfastSchema);
var badBreakfast = new Breakfast({
eggs: 2,
bacon: 1,
drink: 'Milk'
});
var error = badBreakfast.validateSync();
console.log(error.errors);
// {
// eggs : 'Too few eggs',
// drink : '`Milk` is not a valid enum value for path `drink`.'
// }
var userSchema = new Schema({
phone: {
type: String,
validate: {
validator: function(v) {
return /\d{3}-\d{3}-\d{4}/.test(v);
},
message: '{VALUE} is not a valid phone number!'
},
required: [true, 'User phone number required']
}
});
MIDDLEWARES
EVERYWHERE
MIDDLEWARES
MIDDLEWARES
MIDDLEWARES
MIDDLEWARES
MIDDLEWARES
MIDDLEWARES
MIDDLEWARES
MIDDLEWARES
MIDDLEWARES
MIDDLEWARES
MIDDLEWARES
MIDDLEWARES
MIDDLEWARES
MIDDLEWARES
MIDDLEWARES
app.use( (req, res, next) => {
console.log(`Hemos recibido una solicitud a ${req.url}`);
next();
})
Las funciones de middleware son funciones que tienen acceso al objeto de solicitud (req), al objeto de respuesta (res) y a la siguiente función de middleware en el ciclo de solicitud/respuestas de la aplicación. La siguiente función de middleware se denota normalmente con una variable denominada next.
app.use(express.json());
app.use( (req, res, next) => {
console.log(`Yo me ejecuto primero`);
req.invalidUser = true;
next();
})
app.use( (req, res, next) => {
console.log(`Y luego yo`);
if (req.invalidUser) return res.sendStatus(401)
else next()
})
app.use('/api/users', usersRouter);
app.use(express.json());
app.use('/api/users', usersRouter);
app.use( (req, res, next) => {
console.log(`Yo me ejecuto primero`);
req.invalidUser = true;
next();
})
app.use( (req, res, next) => {
console.log(`Y luego yo`);
if (req.invalidUser) return res.status(401).send('Invalid Request')
else next()
})
ERROR HAMIGOH
const express = require('express');
const morgan = require('morgan');
const app = express();
app.use(morgan('combined'));
app.listen(5000);
// Use the session middleware
app.use(session({
secret: 'keyboard cat',
cookie: { maxAge: 60000 },
resave: true,
saveUninitialized: true}))
// Access the session as req.session
app.get('/', function(req, res, next) {
if (req.session.views) {
req.session.views++;
res.setHeader('Content-Type', 'text/html');
res.send(`<p>views: ${req.session.views}</p>
<p>expires in: ${req.session.cookie.maxAge / 1000}s</p>`);
} else {
req.session.views = 1;
res.end('welcome to the session demo. refresh!');
}
})
errorhandler + otros loggers
const app = require('express')();
const errorhandler = require('errorhandler')
const notifier = require('node-notifier');
app.use(errorhandler( { log : errorNotification } ));
app.listen(5000);
function errorNotification (err, str, req) {
var title = 'Error in ' + req.method + ' ' + req.url
notifier.notify({
title: title,
message: str
})
}
errorhandler + otros loggers
const app = require('express')();
const errorhandler = require('errorhandler')
const notifier = require('node-notifier');
if (process.env.NODE_ENV === 'development'){
app.use(errorhandler( { log : errorNotification } ));
}
app.listen(5000);
function errorNotification (err, str, req) {
var title = 'Error in ' + req.method + ' ' + req.url
notifier.notify({
title: title,
message: str
})
}
var compression = require('compression')
var express = require('express')
var app = express()
// compress all responses
app.use(compression())
// add all routes
var cors = require('cors');
var app = require('express')();
app.use(cors());
{
"origin": "*",
"methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
"preflightContinue": false,
"optionsSuccessStatus": 204
}
var app = require('express')();
var cors = require('cors')
var corsOptions = {
origin: ['http://example.com' , 'http://example2.com' ]
}
app.use(cors(corsOptions));
app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')
})