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

A煤n no tienes acceso a esta clase

Crea una cuenta y contin煤a viendo este curso

Guardar el fichero en el servidor

28/33
Recursos

Aportes 33

Preguntas 8

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesi贸n.

var storage = multer.diskStorage({
    destination: function (req, file, cb) {
      cb(null, 'uploads/')
    },
    filename: function (req, file, cb) {
      cb(null, Date.now() + path.extname(file.originalname)) //Appending extension
    }
  })

const upload = multer({
    storage: storage
});```

para agregar la extencion del archivo...
<h1>Aporte:</h1>

realice el siguiente codigo para poder servir img desde mi api con la opcion de modificar la resolucion para optimizar la descarga de img.


const express = require("express");
const multer = require("multer");
const router = express.Router();
const response = require("./../../network/response").error;

const fs = require("fs");
const sharp = require("sharp");
const path = require("path");

router.get("/:type/:width/:height/:fileName", async (req, resp) => {
  const format = req.params.type || "png";
  const width = parseInt(req.params.width) || 255;
  const height = parseInt(req.params.height) || 255;
  const file = req.params.fileName;


  const readStream = fs.createReadStream(
    path.join(__dirname, "./../../upload/", `${file}`)
  );
  readStream.on("error", e => {
    resp.type(`application/json`);
    response(
      req,
      resp,
      "no se encuetnra la img solicitada",
      400,
      "[IMG] no se puede encontrar la img"
    );
  });
  resp.type(`image/${format}`);
  let transform = sharp();
  transform = transform.toFormat(format);
  transform = transform.resize(width, height);
  readStream.pipe(transform).pipe(resp);
});

驴Porqu茅 cuando subo un archivo, no me pone la extensi贸n del mismo?

Un tip: No se equivoquen poniendo localhost/3000, eso me acaba de dar muchos dolores de cabeza.

Para quienes prefieran guardar sus im谩genes con la extensi贸n, pueden configurar multer de esta forma en el network:

// upload files with multer
const storage = multer.diskStorage({
    destination: (req, file, callback) => callback(null, 'public/files'),
    filename: (req, file, callback) => {
        const id = nanoid.nanoid(64);
        const extension = path.extname(file.originalname);
        const fileName = id + extension;
        callback(null, fileName)
  	}
});

const upload = multer({ storage });

Y luego en el controller, se genera el fileUrl asi:

const fileUrl = file 
    ? config.host + ':' + config.port + config.publicRoute + 
       '/files/' + file.filename
    : '';

Tambien les dejo mi metodo para crear el file url:

let fileUrl = '';
  if (req.file) {
    fileUrl = `${req.protocol}://${req.get('host')}/${req.file.destination}${req.file.filename}`;
  }

Por alguna razon, el video anterior tiene el codigo adelantado a esta clase, pero los inicios y finales de estas tres ultimas clases, estan bien. No entiendo que paso alli, pero me causaron una confucion gigantesca, pero bueno a seguir con el curso

Ya veo.
En pr谩ctica estas genial pero en realidad veo 2 inconvenientes:

  1. Se establece una referencia a un directorio interno, en el servidor, el cual estar谩 entrando en colisi贸n cuando haya una mala gesti贸n en memoria. Hay que considerar la eliminaci贸n del mismo como un fs
  2. No se vayan con la finta que mongoDB almacena la informaci贸n, porque hay 2 tipos de almacenamiento, storage y la BD como tal. Por ello, se ocupan CDN o Buckets de almacenamiento en nubes o dedicados en una intranet.

mi aporte, trate de generar la url para no quemar nada y quede escalable por si se llega a desplegar en algun servidor

router.post('/', upload.single('file'), function (req, res) {
    let fileUrl = '';
    if (req.file) {
        fileUrl = `${req.protocol}://${req.get('host')}/${destination}${req.file.filename}`;
    }
    controller.addMessage(req.body.chat, req.body.user, req.body.message, fileUrl)
        .then((response) => responses.success(req, res, response))
        .catch((error) => responses.error(req, res, error, 400, 'Error en el controlador'))
});

En caso que desee hacer una verificaci贸n antes de salvar la imagen, podr铆a ejecutar el middleware o la funci贸n de guardar en una funci贸n dentro del router?

Para probar Multer en un solo fichero, no olviden iniciar el proyecto 鈥渘pm init鈥 e instalar las dependencias 鈥渘pm install express multer鈥

const express = require('express');
const multer = require('multer');
const app = express();

//De no existir el directorio lo crea
//Si no se especifica, crea un directorio diskStorage
const upload = multer({
    dest: 'public/files/',
});

app.use('/public', express.static('public'));

//Se indica a multer que es un solo fichero y que viene en 'file'
app.post('/', upload.single('file'), function (req, res) {
    //req.file guarda la info completa del archivo que hemos subido
    console.log(req.file);
    
	//Sustituir LOCALHOST por http//:localhost:3000
    let fileUrl = 'LOCALHOST' + req.file.path;
    console.log(fileUrl);

    res.send('fichero a帽adido');
});

app.listen(3000, function () {
    console.log('La aplicaci贸n est谩 escuchando en 3000');
});

C贸digo ES:
network

import multer from 'multer';
import path from 'path';

const storage = multer.diskStorage({
    destination : "public/files/",
    filename : function (req, file, cb) {
        cb(null, file.fieldname + "-" + Date.now() + 
        path.extname(file.originalname))
    }
})

const upload = multer({
    storage,
});

router.post('/',upload.single('file'),async (req,res)=>{
    try {
        const { user, message , chat } = req.body;
        const fullMessage = await addMessage(chat, user, message, req.file);
        response.success(req, res, fullMessage, 201);
    } catch (error) {
        response.error(req, res, 'Informacion invalida', 500, 'Error en el desconocido');
    }
});

controller: tuve que separa la url lo vuelves a juntar

const addMessage = (chat, user, message, file)=>{
    return new Promise((resolve, reject)=>{
        if(!chat || !user || !message){
            console.error('[messageController] No hay usuario o mensaje');
            reject('Los datos son incorrectos');
        } else {

            let fileUrl = '';
            if(file){
                fileUrl = `()/app/files/${file.filename}`;
            }

            const fullMessage = {
                chat,
                user,
                message,
                date: new Date(),
                file: fileUrl,
            }
            resolve(fullMessage);
            store.add(fullMessage);
        }
    })
}

Pregunta de examen:
Una vez subido un archivo, 驴se puede hacer algo m谩s con 茅l?

Hola, a los que como a mi no se les descagaba la imagen en cuanto ya generaban su file url y su destino es 鈥減ublic/files/鈥 agreguen esta linea en el archivo routes.js :

server.use(express.static('public'));

tambien les dejo mi funcion para obtener el nombre con extension:

filename: function (req, file, cb) {
    const [name, extension] = file.originalname.split('.');
    cb(null, `${Date.now()}.${extension}`);
  }

Y c贸mo guardamos esas imagenes directamente en base de datos ?

Como hago para recibir un arreglo de imagenes?

quedo perfecto mi subida de archivos

en desarrollo me funciona perfecto,
pero hice deploy con now y me lanza el status 500
por esta razon鈥

Error: ENOENT: no such file or directory, open 'public/files/1574784627297-l-c.png'

Que sencillo es hacer esto con multer

**Error: ENOENT: no such file or directory, open 鈥楥:\Users鈥uploads\1573012846127.jpg鈥 **

Si no tengo la carpeta uploads ya creada, me sale ese error鈥
Tuve que modificar la function destination as铆:
var storage = multer.diskStorage({ destination: 'public/files/', ...

Est谩n invertidos los videos, creo que este va primero.

El paquete de multer es genial, nos facilita mucho las cosas

Es rid铆culamente sencillo manejar archivos, en otros lenguajes tengo que lidiar con muchos problemas, excelente curso Carlos.

Excelente multer

Wow. Increible este curso!!!

馃槷鉁

Qu茅 puede ocacionar este error? (node:3496) UnhandledPromiseRejectionWarning: ValidationError: Message validation failed: chat: Cast to ObjectId failed for value 鈥1234鈥 at path 鈥渃hat鈥

Les dejo un codigo para agregar la extension, sin tener que instalar tanta depedencia

const storage = multer.diskStorage({
    destination: 'uploads/',
    filename: function(req, file, callback){
        const [name, extension] = file.originalname.split('.');
        callback(null, `${name}-${Date.now()}.${extension}` )        
    }
})

const upload = multer({
    storage: storage,
});

Aca les dejo mi repo de github con esta ultima section en Typescript:
Tag: dbrelations-section
link:https://github.com/Aibique-stage1/telegram-backend-js/tree/dbrelations-section

Ayuda por favor me aparece este mensaje de error, MongoError: E11000 duplicate key error collection: test.messages index: chat_1 dup key: { chat: ObjectId(鈥5fffd970b5d1f3230d415a6c鈥) }

Este es mi esquema

const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const mySchema = new Schema({
  chat: {
    type: Schema.ObjectId,
    ref: "Chat",
    required: true,
  },
  user: {
    type: Schema.ObjectId,
    ref: "User",
    required: true,
  },
  message: {
    type: String,
    required: true,
  },
  date: Date,
  file: String,
});

const model = mongoose.model("Message", mySchema);
module.exports = model;```

Muy genial!! 馃槂

Increiblemente facil鈥
Otro modulo que podemos usar es el connect-multiparty, tambien es my facil de usar.

Qued贸 explendido mi subida de archivos