PERSISTENCIA DE NUESTROS DATOS
Esta vez, no en ficheros, sino en una base de datos


REPASO
ROUTER
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);
router + module.exports
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
Y si ...
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
Y si ...

Y si ...
index.js 10 líneas
api/users/index.js 8 líneas



api/users/users.controller.js 60 líneas
PERSISTENCIA DE NUESTROS DATOS
Esta vez, no en ficheros, sino en una base de datos
SQL
NO-SQL
GRAFOS
¿ 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


DESCARGAMOS E INSTALAMOS
MONGODB

Si todo ha ido bien ...
Ejecutamos en una terminal
mongod o la ruta completa al .exe
y nos dirá que está listo y escuchando en el puerto 27017
Si queremos acceder a la consola
Para acceder a la consola de mongo una vez tengamos el mongod corriendo debemos de ejecutar el comando/ejecutable mongo
¡ AL LÍO !

En la terminal "creamos" una db
use NOMBREBD
db.createCollection()

show collections

db.users.insert( { } );

db.users.find( { } );

db.customers.find( { } ).pretty()

db.customers.update( { }, { } )
vs


db.customers.update( { }, { $set : { key : value } } )
db.customers.update( { }, { } )
db.customers.update( { }, { $set : { key : value } } )
vs


Machacaría todos los otros atributos
.update( {}, {} , { upsert : true )
.update({},{$rename :{ clave : clave2 }})
db.customers.remove( { } )

db.customers.remove( { }, {justOne : true} )
nuevos métodos
db.users.insertOne()
db.users.insertMany()
db.users.deleteOne()
db.users.deleteMany()
db.users.updateOne()
db.users.updateMany()
db.users.replaceOne()
query
resultado.sort( { createdAt : 1, other : 0 })
resultado.limit( 10 )
resultado.forEach ( ) :O
resultado.map ( ) :O
resultado.count()

query
resultado.sort( { createdAt : 1, other : 0 })
resultado.limit( 10 )
resultado.forEach ( ) :O
resultado.map ( ) :O
resultado.count()

Ejercicios
Crea una nueva bd llamada pruebas. Dentro de ella crea una colleción llamada TODOS e importa el json de jsonplaceholder
Realiza los siguientes consultas:
Ejercicios
- Cuenta el número de to-do's.
- Cuenta el número de to-do's del usuario 6.
- Cuenta el número de to-do's que tienen un id mayor del 140.
- Cuenta el número de to-do's que están completados.
- Cambia todos los to-do's del usuario 5 a completed = true.
- Renombra el atributo title por content.
- Devuelve los 10 últimos to-do's.
- Devuelve por consola para los 5 últimos to-do's un mensaje así : "El to-do con el texto 'loquesea' pertenece al usuario con id: 'id'"
Ejercicios
- Inserta 10 nuevos to-do's para el usuario con id 88
- Borra todos los to-do's del usuario 3 y del usuario 4
- Encuentra los to-do's del usuario 2 y cambiales el id del usuario por el 5
Alternativas a la consola
Conectando mongo con nodejs
mongodb-driver
const mongodb = require('mongodb');
mongodb.connect('mongodb://localhost', function (err, client) {
if (err) return console.error(err);
const db = client.db('todolist');
console.log("Connected successfully to server");
const todosCollection = db.collection('todos');
todosCollection.find({}).toArray((err, response) => {
console.log(response);
client.close();
})
});
const mongodb = require('mongodb');
mongodb.connect('mongodb://localhost', function (err, client) {
if (err) return console.error(err);
const db = client.db('todolist');
console.log("Connected successfully to server");
const todosCollection = db.collection('todos');
todosCollection.insertMany([{},{}] , (err, response) => {
console.log(response.result);
console.log(response.result.n);
client.close();
})
});
Mini ejercicio
Instalar el mongodb-driver y verifica que está todo bien haciendo un find a tu collección de todos e imprimiendo por consola el .length de los todos encontrados

Librerías ODM
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
Sigamos

Vamos a cobrar más

Vamos a cobrar más
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;
Fichero : /api/todos/todos.model.js
Vamos a cobrar más
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
Vamos a cobrar más
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
Vamos a cobrar más
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í
Vamos a cobrar más
A currar
Guarda tus datos del proyecto de twitter en mongodb y usa mongoose para conectar tu api con la base de datos. NO HAGAS VALIDACIONES
¡UN PASO MÁS ALLÁ !

MONGOOSE TE PERMITE PONER 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;
}
}
});
¿Cómo uso esto?
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`.'
// }
Otra ejemplo más
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']
}
});
Aplica las validaciones en tus Schemas
Aplica paginación a la api :O queryParams investiga como paginar una búsqueda de mongoose ¡investiga tanto el limit como el skip y parametrízalos !
API
FrontEnd
2 caminos
Llegó el momento de hacerle un
pequeño frontal a ese "twitter" no ?
Katas
Tenemos trozos de 20 minutos para hacer un todolist front+back
Grupos de 3 que cambian cada ronda
Api Restful Con MongoDB
By Yunior González Santana
Api Restful Con MongoDB
Añadimos persistencia a nuestros datos en este caso con MongoDB
- 165