Conocer y comprender c贸mo se realizan las conexiones hacia los servidores a trav茅s de internet y sus implicaciones en el desarrollo de servidores

1

Bienvenida y presentaci贸n del curso

2

Qu茅 es Node y c贸mo instalarlo

3

驴Qu茅 son y c贸mo se usan las peticiones HTTP?

4

M茅todos, cabeceras y estados

5

Cuerpo y query de la petici贸n

Crear un servidor HTTP en Javascript, y comenzar a escuchar y responder peticiones desde un cliente .

6

Crear un servidor HTTP desde NodeJS

7

驴C贸mo pueden venir las peticiones?

8

Recibir informaci贸n desde el cliente: Body y Query

9

Informaci贸n contextual: Leer las cabeceras

10

Tipos de respuesta: Vac铆a, plana, con datos y estructurada

11

Respuestas coherentes

12

Servir archivos est谩ticos

13

Errores: C贸mo presentarlos e implicaciones en la seguridad

Comprender y desarrollar la arquitectura b谩sica de un backend en NodeJS, y comunicarse entre m贸dulos

14

Conceptualmente: Rutas, controladores y bases de datos

15

Rutas y capa de red: Responsabilidades y l铆mites

16

Controladores: Definiendo la l贸gica de negocio

17

Almacenando la informaci贸n en una base de datos

Utilizar una base de datos para definir, modelar, almacenar y recuperar la informaci贸n de nuestra aplicaci贸n

18

Tipos de Bases de Datos: Relacionales y No Relacionales

19

Crear y Configurar tu Base de Datos con MongoDB

20

MongoDB: Almacenar y leer datos

21

MongoDB: Actualizar datos

22

MongoDB: Consultar datos

23

MongoDB: Eliminar Datos

24

Gestionar conexiones a la base de datos desde la API

Uso de entidades para crear aplicaciones escalables

25

Escalando la arquitectura: M煤ltiples entidades

26

Relacionando nuestras entidades

27

C贸mo recibir ficheros desde NodeJS

28

Guardar el fichero en el servidor

Conocer el protocolo de websockets, e implementar comunicaci贸n cliente/servidor con SocketIO.

29

WebSockets: Qu茅 son, por qu茅 son interesantes y c贸mo usarlos

30

Manejo de Websockets con NodeJS

31

Conectar la API al servidor de WebSockets

Revisi贸n de lo aprendido, y pr贸ximos pasos

32

Revisi贸n y pr贸ximos pasos

33

Tips para escalar nuestro proyecto

No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

MongoDB: Consultar datos

22/33
Recursos

Aportes 24

Preguntas 7

Ordenar por:

Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Reg铆strate o inicia sesi贸n para participar.

En caso de que queramos hacer una b煤squeda por el nombre ignorando may煤sculas o min煤sculas se puede implementar el siguiente c贸digo:

  let userFilter = {};
  if (user) {
    userFilter.user = new RegExp(user, "i");
  }

Mongo puede utilizar Regular Expressions para realizar b煤squedas y en estas es posible indicarle que busque 鈥渃ase-insensitive鈥. Esto se logra con el flag 鈥渋鈥 que vemos en el c贸digo. Este c贸digo se traduce a: /usuario/i.
.
Platzi cuenta con un curso de RegExp por si alguien quiere tomarlo 馃槂 https://platzi.com/clases/expresiones-regulares/

Con la especificacion del metodo getMessages del store.js vista en esta clase, al no especificar el parametro user en el query, se retornara un arreglo vacio. Esto depende de la definicion y alcance del metodo getMessages, pero si en caso yo quisiera obtener toda la lista de usuarios usando dicho metodo cuando no se especifica el parametro query de user, es solo cambiar la condicion de existencia del parametro filterUser

const get Messages = async (filterUser) => {
    let filter = {}
    if (filterUser) 
   // ... aqui sigue la misma definicion de metodo :D
}

Comparto el c贸digo para filtrar tambi茅n por el texto del mensaje:

  • store.js:
async function getMessages(filterUser, filterMessage) {
    let filter = {}

    if (filterUser){
        filter = {
            user: filterUser
        }
    }
    
    if (filterMessage){
        filter = {
            ...filter,
            message: filterMessage
        }
    }

    return await Model.find(filter)
}
  • controller.js
function getMessages(filterUser, filterMessage) {
    return new Promise((resolve, reject) => {
        try {
            resolve(store.list(filterUser, filterMessage))
        } catch (error) {
            reject(error)
        }
    })
}
  • network.js
router.get('/', function (req, res) {
    const filterUser = req.query.user || null
    const filterMessage = req.query.message || null

    console.log(filterUser)

    controller.getMessages(filterUser, filterMessage)
        .then(messagesList => {
            response.success(req, res, messagesList, 200)
        })
        .catch( e => {
            response.error(req, res, 'Unexpected error' /*  user message */, 500, e)
        })
})

verifique que si el usuario no existe le diera la respuesta.

store.js

async function getMessage(filterByUser) {
  let filterUser = {};
  if (filterByUser !== null) {
    //Le decimos a mongo que solo nos muestre informacion de ese user (si viene alguno)
    filterUser = { user: filterByUser };
  }
  const messages = await Model.find(filterUser);
  //Verificamos que el usuario exista.
  if (messages.length !== 0) {
    return messages;
  } else {
    console.log("Usuario no se encuenta en la base de datos");
    return "Usuario no encontrado";
  }
}

Aqu铆 ten茅is un ejemplo de como se hace un filtro por diferentes par谩metros.

message.get("/", async (req, res) => {
  /* Creamos el filtro de b煤squeda */
  let filter = {};
  const { user = null, message = null } = req.query;
  user && (filter.user = new RegExp(user, "i"));
  message && (filter.message = new RegExp(message, "i"));
  /* Hacemos la consulta */
  try {
    const list = await controller.getMessages(filter);
    success({ req, res, data: list, status: 201 });
  } catch (info) {
    error({ req, res, error: "error", status: 500, info });
  }
});

Podr铆amos tambi茅n pasar el usuario como:
鈥/message/user/:name 鈥?

Cual ser铆a la mejor forma???

si yo quiero hacer la siguiente consulta ++**SQL SELECT * FROM messages WHERE user LIKE 鈥%carl%鈥 **++en mongo con node
驴C贸mo ser铆a?

Genial! Tambi茅n puede hacerse mas corto de la siguiente forma en el store.js:

let listUsers = async (filterUser) => { 

    if(filterUser!=null) { filterUser = {user : filterUser} }
    const users = await Model.find(filterUser) 
    return users
}

En este caso, el filtro lo deber铆a establecer el cliente desde el frontend, verdad? Desde el backend buscamos en la BD con el filtro y devolvemos lo que el usuario quiera ver.

La b煤squeda ya un poco m谩s elaborada, lo bueno que tiene este c贸digo es que se puede ir
agregando campos al modelo de tipo string y deber铆a seguir funcionando, para todos los campos string,
tambi茅n aplique el truco de usar regex en la consulta para que pueda buscar valores parciales.

// messages_controller.js

const store = require("./messages_store");
const modelProps = store.getModelProps();
const modelStringProps = store.getModelProps("string");

function listMessages(query) {
  return new Promise(async (resolve, reject) => {
    try {
      const search_query = getSearchQuery(query);
      if (!search_query) {
        resolve([]);
        return;
      }

      const messages = await store.list(search_query);
      resolve(messages);
    } catch (error) {
      console.error("[Error listMessages]:", error.stack);
      reject(error);
    }
  });
}

function getSearchQuery(query) {
  for (let [property, value] of Object.entries(query)) {
    if (!modelProps.includes(property)) {
      return false;
    }

    if (modelStringProps.includes(property)) {
      if (typeof value === "string") value = [value];
      query[property] = new RegExp(value.join("|"), "i");
    }
  }
  return query;
}

// messages_store.js

const Model = require("./messages_model");
Model.schemaProps = Object.keys(Model.schema.obj);

async function list(query) {
  const all_documents = await Model.find(query);
  return all_documents;
}

function getModelProps(filter_type) {
  return Model.schemaProps.filter((prop) => {
    if (filter_type) {
      const propType = Model.schema.paths[prop].instance.toLowerCase();
      const is_filter_type = propType === filter_type.toLowerCase();
      return is_filter_type ? prop : null;
    }
    return prop;
  });
}

module.exports = {
  list,
  getModelProps
};

Codigo ES6+:

Ruta: componente/message/network.js

router.get('/',async (req,res)=>{
    try {
        const filterUser = req.query.user || null;
        const messages = await getMessages(filterUser);
        response.success(req, res, messages, 200);
    } catch (e) {
        response.error(req, res, 'Error inesperado', 500, e);
    }
});

Ruta: componente/message/controller.js

const getMessages = (filterUser)=> {
    return new Promise((resolve,reject)=>{
        resolve(store.list(filterUser));
    })
}

Ruta: componente/message/store.js

async function getMessages(filterUser) {
    let filter ={}

    if(filterUser != null)filter ={ user: new RegExp(`${filterUser}`,'i') }
    const messages = await Model.find(filter);
    return messages;
}

No se le pudo seguir el ritmo a la parte de mongo porque mlab ya no prensta la info de esta manera.

Para quitar el __v y para anadir la fecha ademas de constrains a los datos del modelo:

const userSchema = new Schema({
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
}, {
timestamps: true, // agrega la fecha de creacion y actualziacion
versionKey: false //quita el __v
})

Vaina me toca repasar mucho Mongo DB. Hay muchas cosas que no entiendo a profundidad.

Wow genial aprender estas cosas

I teresante

filter === select?

Todo Muy interesante 馃槂

Igual es posible simpleifiar el if por un valor trusty en caso de que este vacio dara false

async function getMessage(filterUser){
  let filter = {};
  if(filterUser){
    filter = { user: filterUser}
  }
  const messages = await Model.find(filter);
  return messages;
}```

Actualmente tengo dos colecciones, que se encuentran referenciadas por un id, como imprimo un valor dentro de la referencia, si quisiera imprimir los datos del empleado y un campo de la referencia de tipo sangre como estatus sin traerme el id.

const users = await Empleado.find();
console.log(users.tipo_sangre.nombre);

const EmpleadoSchema = new Schema(
    {
        num_seguro_social: {   
            type: String, 

            maxlength: [20, "Tama帽o Maximo para numero de seguro social 20 caracteres"],
            unique:true,
            trim:true
        },
        tipo_sangre:{
                type:Schema.Types.ObjectId,
                ref:"cat_tps"
        }
    },
    {
        timestamps: true
    }
    );

const cat_tps = new Schema ({

    nombre:{
        type: String,
        require: true
    },

    status: {
        type: Boolean,
        default:true
    }
});

Super 馃槂 鉁

Recomiendo hacer la validacion en el network o controller, ya que la logica deberia ir ahi y no en el store.
Ejemplo:

  • Network.js
const {user: filteredUser} = req.query;
const filter = filteredUser ?{ user: filteredUser } :{}
...
getMessages(filter)

Pr谩ctica: se me queda cargando en insomnia. 馃槮

Me encanta la simplicidad de este curso pero me quedan dudas con la seguridad