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

No se trata de lo que quieres comprar, sino de quién quieres ser. Aprovecha el precio especial.

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

15 Días
4 Hrs
4 Min
3 Seg

Guardar el fichero en el servidor

28/33
Recursos

Aportes 35

Preguntas 10

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

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);
});

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

¿Porqué cuando subo un archivo, no me pone la extensión del mismo?

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

A mi me funciono así:

const storage = multer.diskStorage({
    destination : "public/file/",
    filename : function (req, file, cb) {
        cb(null, file.originalname)
    }
});
const upload = multer({
    storage:storage
})
const {mongo} = require("../db/mongo");
const postModel = require('../models/PostModel');
const fs = require('fs');

 const AddPost = async (req, res, next) => {
     console.log(req.file)

      const image = await fs.readFileSync(req.file.path,'base64');

     //delete imagen
     fs.unlinkSync(req.file.path, (err) => {
            if(err) throw err;
     })
     const { title, body,user } = req.body;
     const newPost = new postModel({
         title,
         body,
         image,
         user
     });
     newPost.save().then(r => {
         console.log(r)
         return res.send('Insert User');
     }).catch(err => {
         return res.status(403).send('No se pudo insertar el dato')
     });
 }

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'))
});

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

Hola, a los que como a mi no se les descagaba la imagen en cuanto ya generaban su file url y su destino es “public/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}`);
  }

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.

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?

Pregunta de examen:
Una vez subido un archivo, ¿se puede hacer algo más con él?

Para probar Multer en un solo fichero, no olviden iniciar el proyecto “npm init” e instalar las dependencias “npm 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);
        }
    })
}

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 ‘C:\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 “chat”

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