5-Express--Curso de Node.js [ #05 Introducción a Express.js ]

Express: Dominando Servidores Web con Node.js y Express

  5- EXPRESS
           |
          V

mi-app/
├app.js
└── package.json

1. Introducción a Express

Express es el framework web más popular para Node.js. Simplifica la creación de servidores HTTP con:
✔️ Enrutamiento intuitivo
✔️ Sistema de middleware potente
✔️ Manejo simplificado de requests/responses
✔️ Compatibilidad con múltiples motores de plantillas

bash
Copy
Download
# Iniciar proyecto
npm init -y
npm install express

permiso solo para la sesión actual)

Ejecuta en PowerShell como Administrador:

powershell
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

Luego vuelve a ejecutar npm init -y. Este cambio solo dura mientras la ventana de PowerShell esté abierta.


2. Servidor Básico en 4 Pasos

Archivo: app.js

javascript
Copy
Download
// 1. Importar Express
const express = require('express');

// 2. Crear aplicación
const app = express();
const PORT = 3000;

// 3. Definir ruta principal
app.get('/', (req, res) => {
  res.send('🎉 ¡Servidor Express funcionando!');
});

// 4. Iniciar servidor
app.listen(PORT, () => {
  console.log(`Servidor corriendo en http://localhost:${PORT}`);
});

app.use() es un método que monta middlewares (funciones intermedias) que se ejecutan antes de que lleguen a tus rutas.

Regla de oro:

  • app.use() → Se ejecuta para TODOS los métodos HTTP (GET, POST, PUT, DELETE)

  • app.get() → Solo para peticiones GET

  • app.post() → Solo para peticiones POST

Ejecutar:

bash
Copy
Download
node app.js

3. Manejo de Rutas Esencial

Rutas básicas

javascript
Copy
Download
// GET
app.get('/productos', (req, res) => {
  res.send('Lista de productos');
});

// POST
app.post('/productos', (req, res) => {
  res.send('Producto creado');
});

Archivo: app.js

javascript
Copy
Download
// 1. Importar Express
const express = require('express');

// 2. Crear aplicación
const app = express();
const PORT = 3000;

// 3. Definir ruta principal
app.get('/', (req, res) => {
  res.send('🎉 ¡Servidor Express funcionando!');
});

// GET
app.get('/productos', (req, res) => {
  res.send('Lista de productos');
});
// 4. Iniciar servidor app.listen(PORT, () => { console.log(`Servidor corriendo en http://localhost:${PORT}`); });

Rutas con parámetros

javascript
Copy
Download
app.get('/usuarios/:id', (req, res) => {
  res.send(`Usuario ID: ${req.params.id}`);
});

// Ejemplo: /usuarios/123 → "Usuario ID: 123"

Múltiples métodos

javascript
Copy
Download
app.route('/libros')
  .get((req, res) => res.send('Obtener libros'))
  .post((req, res) => res.send('Crear libro'));

Código completo (solo GET) - app.js

javascript
const express = require('express');
const app = express();
const PORT = 3000;

// Datos de ejemplo
const productos = [
  { id: 1, nombre: 'Laptop', precio: 1000 },
  { id: 2, nombre: 'Mouse', precio: 25 },
  { id: 3, nombre: 'Teclado', precio: 50 }
];

// ============ RUTAS SOLO GET ============

// GET - Obtener todos los productos
app.get('/productos', (req, res) => {
  res.json({
    success: true,
    cantidad: productos.length,
    productos: productos
  });
});

// GET - Obtener un producto específico por ID
app.get('/productos/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const producto = productos.find(p => p.id === id);
  
  if (!producto) {
    return res.status(404).json({ error: 'Producto no encontrado' });
  }
  
  res.json(producto);
});

// Ruta principal
app.get('/', (req, res) => {
  res.send(`
    <h1>API de Productos - Solo GET</h1>
    <h3>Endpoints disponibles:</h3>
    <ul>
      <li><a href="/productos">GET /productos</a> - Ver todos los productos</li>
      <li>GET /productos/:id - Ver un producto específico</li>
    </ul>
    <h3>Ejemplos:</h3>
    <ul>
      <li><a href="/productos/1">Ver producto ID 1</a></li>
      <li><a href="/productos/2">Ver producto ID 2</a></li>
      <li><a href="/productos/3">Ver producto ID 3</a></li>
    </ul>
  `);
});

// Iniciar servidor
app.listen(PORT, () => {
  console.log(`🚀 Servidor corriendo en http://localhost:${PORT}`);
  console.log(`📦 Ver productos: http://localhost:${PORT}/productos`);
});

Cómo probar (solo GET)

4. Middleware Clave

Funciones que procesan requests antes de llegar a las rutas:

Middleware incorporado

javascript
Copy
Download
// Parsear JSON
app.use(express.json());

// Parsear formularios
app.use(express.urlencoded({ extended: true }));

// Servir archivos estáticos
app.use(express.static('public'));

Middleware personalizado

javascript
Copy
Download
// Logger de solicitudes
app.use((req, res, next) => {
  console.log(`${req.method} ${req.url}`);
  next(); // Continuar al siguiente middleware
});

5. Manejo de Errores

javascript
Copy
Download
// Ruta no encontrada (404)
app.use((req, res) => {
  res.status(404).send('Página no encontrada');
});

// Manejador global de errores
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send('¡Error en el servidor!');
});

6. Estructura Profesional

Copy
Download
mi-app/
├── controllers/
│   └── userController.js
├── routes/
│   └── userRoutes.js
├── public/
├── app.js
└── package.json

Ejemplo modular:

javascript
Copy
Download
// routes/userRoutes.js
const router = express.Router();

router.get('/', (req, res) => {
  res.send('Lista de usuarios');
});

module.exports = router;

// app.js
const userRoutes = require('./routes/userRoutes');
app.use('/usuarios', userRoutes);

7. Nodemon para Desarrollo

Instalación:

bash
Copy
Download
npm install --save-dev nodemon

Configurar en package.json:

json
Copy
Download
"scripts": {
  "start": "node app.js",
  "dev": "nodemon app.js"
}

Uso:

bash
Copy
Download
npm run dev  # Recarga automática al guardar cambios

8. Extendiendo Express

Motor de plantillas (EJS):

bash
Copy
Download
npm install ejs
javascript
Copy
Download
app.set('view engine', 'ejs');
app.get('/', (req, res) => {
  res.render('index', { title: 'Inicio' });
});

API REST básica:

javascript
Copy
Download
app.get('/api/usuarios', (req, res) => {
  res.json([{ id: 1, nombre: 'Juan' }]);
});

 ¿Qué hace app.set('view engine', 'ejs') en Express.js?

Si estás trabajando con Node.js y Express, es probable que hayas visto la línea app.set('view engine', 'ejs') en tu código. Pero, ¿qué significa exactamente y por qué es importante?

En este artículo, te explico cómo funciona esta configuración y cómo te ayuda a renderizar páginas dinámicas en tu aplicación web.


2. ¿Para qué sirve app.set('view engine', 'ejs')?

La línea:

javascript
Copy
Download
app.set('view engine', 'ejs');

le dice a Express que usará EJS como motor de plantillas predeterminado. Esto significa que:

No necesitas especificar la extensión al renderizar vistas:

javascript
Copy
Download
res.render('home'); // Buscará automáticamente "home.ejs"

Permite incrustar JavaScript en HTML:
Con EJS, puedes hacer cosas como:

html
Copy
Download
Run
<h1>Hola, <%= username %>!</h1>

Facilita la organización de vistas:
Express buscará las plantillas en la carpeta views/ por defecto.

Resumen de cómo funciona POST:

  1. Cliente envía datos JSON al servidor

  2. Express usa express.json() middleware para parsear el JSON

  3. Ruta POST recibe los datos en req.body

  4. Servidor procesa y guarda los datos

  5. Respuesta confirma la creación con status 201

¿Necesitas que te explique alguna parte específica más a detalle?


🚀 Conclusión

Express te permite crear:

  • APIs RESTful

  • Aplicaciones web con SSR

  • Microservicios

  • Backends para frontends (React, Vue, etc.)

Próximos pasos:

  1. Conexión a bases de datos (MongoDB/PostgreSQL)

  2. Autenticación (JWT, Passport.js)

  3. Validación de datos (express-validator)

bash
Copy
Download
# Plantilla Express completa
npx express-generator --view=ejs




d


*********************************

Código completo (solo GET) - app.js

javascript
const express = require('express');
const app = express();
const PORT = 3000;

// Datos de ejemplo
const productos = [
  { id: 1, nombre: 'Laptop', precio: 1000 },
  { id: 2, nombre: 'Mouse', precio: 25 },
  { id: 3, nombre: 'Teclado', precio: 50 }
];

// ============ RUTAS SOLO GET ============

// GET - Obtener todos los productos
app.get('/productos', (req, res) => {
  res.json({
    success: true,
    cantidad: productos.length,
    productos: productos
  });
});

// GET - Obtener un producto específico por ID
app.get('/productos/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const producto = productos.find(p => p.id === id);
  
  if (!producto) {
    return res.status(404).json({ error: 'Producto no encontrado' });
  }
  
  res.json(producto);
});

// Ruta principal
app.get('/', (req, res) => {
  res.send(`
    <h1>API de Productos - Solo GET</h1>
    <h3>Endpoints disponibles:</h3>
    <ul>
      <li><a href="/productos">GET /productos</a> - Ver todos los productos</li>
      <li>GET /productos/:id - Ver un producto específico</li>
    </ul>
    <h3>Ejemplos:</h3>
    <ul>
      <li><a href="/productos/1">Ver producto ID 1</a></li>
      <li><a href="/productos/2">Ver producto ID 2</a></li>
      <li><a href="/productos/3">Ver producto ID 3</a></li>
    </ul>
  `);
});

// Iniciar servidor
app.listen(PORT, () => {
  console.log(`🚀 Servidor corriendo en http://localhost:${PORT}`);
  console.log(`📦 Ver productos: http://localhost:${PORT}/productos`);
});

Cómo probar (solo GET)

Método 1: Navegador web (más fácil)

bash
# Ejecutar el servidor
node app.js

# Abrir en el navegador:
http://localhost:3000/productos
http://localhost:3000/productos/1
http://localhost:3000/productos/2

Método 2: Terminal con curl

bash
# Ver todos los productos
curl http://localhost:3000/productos

# Ver producto específico
curl http://localhost:3000/productos/1

Método 3: PowerShell (Windows)

powershell
# Ver todos los productos
Invoke-WebRequest -Uri http://localhost:3000/productos | Select-Object -ExpandProperty Content

# Ver producto específico
Invoke-WebRequest -Uri http://localhost:3000/productos/1 | Select-Object -ExpandProperty Content

Instalación y ejecución

bash
# 1. Inicializar proyecto
npm init -y

# 2. Instalar express
npm install express

# 3. Crear archivo app.js con el código de arriba

# 4. Ejecutar
node app.js

Probar con Nodemon (opcional)

bash
# Instalar nodemon
npm install --save-dev nodemon

# En package.json agregar:
"scripts": {
  "start": "node app.js",
  "dev": "nodemon app.js"
}

# Ejecutar en modo desarrollo
npm run dev

Salida esperada en el navegador

http://localhost:3000/productos

json
{
  "success": true,
  "cantidad": 3,
  "productos": [
    { "id": 1, "nombre": "Laptop", "precio": 1000 },
    { "id": 2, "nombre": "Mouse", "precio": 25 },
    { "id": 3, "nombre": "Teclado", "precio": 50 }
  ]
}

http://localhost:3000/productos/1

json
{ "id": 1, "nombre": "Laptop", "precio": 1000 }

http://localhost:3000/productos/99

json
{ "error": "Producto no encontrado" }

¡Listo! Esta versión solo usa GET para consultar productos. No incluye POST, PUT ni DELETE

*************

Proyecto completo

1. Estructura del proyecto

text
mi-app/
├── app.js
├── package.json
└── public/

2. Código completo (app.js)

javascript
const express = require('express');
const app = express();
const PORT = 3000;

// MIDDLEWARE IMPORTANTE para POST
app.use(express.json()); // Para recibir JSON
app.use(express.urlencoded({ extended: true })); // Para formularios

// ARRAY para almacenar productos (simulando BD)
let productos = [
  { id: 1, nombre: 'Laptop', precio: 1000 },
  { id: 2, nombre: 'Mouse', precio: 25 }
];

// ============ RUTAS ============

// GET - Obtener todos los productos
app.get('/productos', (req, res) => {
  res.json({
    success: true,
    cantidad: productos.length,
    productos: productos
  });
});

// GET - Obtener un producto específico
app.get('/productos/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const producto = productos.find(p => p.id === id);
  
  if (!producto) {
    return res.status(404).json({ error: 'Producto no encontrado' });
  }
  
  res.json(producto);
});

// POST - Crear nuevo producto
app.post('/productos', (req, res) => {
  const { nombre, precio } = req.body;
  
  // Validación básica
  if (!nombre || !precio) {
    return res.status(400).json({ 
      error: 'Faltan datos. Se requiere: nombre y precio' 
    });
  }
  
  // Crear nuevo producto
  const nuevoProducto = {
    id: productos.length + 1,
    nombre: nombre,
    precio: precio
  };
  
  productos.push(nuevoProducto);
  
  res.status(201).json({
    mensaje: 'Producto creado exitosamente',
    producto: nuevoProducto
  });
});

// PUT - Actualizar producto
app.put('/productos/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const { nombre, precio } = req.body;
  const productoIndex = productos.findIndex(p => p.id === id);
  
  if (productoIndex === -1) {
    return res.status(404).json({ error: 'Producto no encontrado' });
  }
  
  productos[productoIndex] = { ...productos[productoIndex], nombre, precio };
  
  res.json({
    mensaje: 'Producto actualizado',
    producto: productos[productoIndex]
  });
});

// DELETE - Eliminar producto
app.delete('/productos/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const productoIndex = productos.findIndex(p => p.id === id);
  
  if (productoIndex === -1) {
    return res.status(404).json({ error: 'Producto no encontrado' });
  }
  
  const productoEliminado = productos.splice(productoIndex, 1);
  
  res.json({
    mensaje: 'Producto eliminado',
    producto: productoEliminado[0]
  });
});

// Ruta principal
app.get('/', (req, res) => {
  res.send(`
    <h1>API de Productos</h1>
    <h3>Endpoints disponibles:</h3>
    <ul>
      <li>GET /productos - Ver todos los productos</li>
      <li>GET /productos/:id - Ver un producto específico</li>
      <li>POST /productos - Crear nuevo producto</li>
      <li>PUT /productos/:id - Actualizar producto</li>
      <li>DELETE /productos/:id - Eliminar producto</li>
    </ul>
    <h3>Ejemplo POST con fetch:</h3>
    <pre>
      fetch('http://localhost:3000/productos', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          nombre: 'Teclado',
          precio: 50
        })
      })
      .then(res => res.json())
      .then(console.log)
    </pre>
  `);
});

// Middleware 404
app.use((req, res) => {
  res.status(404).json({ error: 'Ruta no encontrada' });
});

// Iniciar servidor
app.listen(PORT, () => {
  console.log(`🚀 Servidor corriendo en http://localhost:${PORT}`);
  console.log(`📦 Endpoint productos: http://localhost:${PORT}/productos`);
});

3. Cómo probar POST (4 métodos)

Método 1: Postman (más fácil)

  1. Descarga Postman desde https://www.postman.com

  2. Configuración:

    • Method: POST

    • URL: http://localhost:3000/productos

    • Headers: Content-Type: application/json

    • Body → raw → JSON:

    json
    {
      "nombre": "Monitor",
      "precio": 350
    }

Método 2: Thunder Client (extensión VS Code)

  1. Instala extensión "Thunder Client"

  2. Crea nueva request:

    • POST → http://localhost:3000/productos

    • JSON Body: {"nombre": "Tablet", "precio": 200}

Método 3: curl (terminal)

bash
# En Windows PowerShell o Git Bash
curl -X POST http://localhost:3000/productos `
  -H "Content-Type: application/json" `
  -d "{\"nombre\":\"Audifonos\",\"precio\":45}"

# O más legible
curl -X POST http://localhost:3000/productos `
  -H "Content-Type: application/json" `
  -d "{\"nombre\":\"Webcam\",\"precio\":80}"

Método 4: HTML con JavaScript (archivo independiente)

Crea public/test.html:

html
<!DOCTYPE html>
<html>
<head>
    <title>Probar API Productos</title>
</head>
<body>
    <h1>Probar API Productos</h1>
    
    <h3>Crear Producto (POST)</h3>
    <input type="text" id="nombre" placeholder="Nombre">
    <input type="number" id="precio" placeholder="Precio">
    <button onclick="crearProducto()">Crear</button>
    
    <h3>Ver Productos (GET)</h3>
    <button onclick="verProductos()">Ver todos</button>
    <div id="resultado"></div>
    
    <script>
        async function crearProducto() {
            const nombre = document.getElementById('nombre').value;
            const precio = document.getElementById('precio').value;
            
            const response = await fetch('http://localhost:3000/productos', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ nombre, precio: parseInt(precio) })
            });
            
            const data = await response.json();
            document.getElementById('resultado').innerHTML = 
                '<pre>' + JSON.stringify(data, null, 2) + '</pre>';
        }
        
        async function verProductos() {
            const response = await fetch('http://localhost:3000/productos');
            const data = await response.json();
            document.getElementById('resultado').innerHTML = 
                '<pre>' + JSON.stringify(data, null, 2) + '</pre>';
        }
    </script>
</body>
</html>

4. Ejecutar y probar paso a paso

bash
# 1. Instalar dependencias
npm init -y
npm install express

# 2. Crear app.js con el código completo

# 3. Ejecutar servidor
node app.js

# 4. Probar rutas:
# GET (abrir en navegador)
http://localhost:3000/productos

# POST (en otra terminal)
curl -X POST http://localhost:3000/productos -H "Content-Type: application/json" -d "{\"nombre\":\"iPad\",\"precio\":500}"

5. Con Nodemon (desarrollo)

bash
npm install --save-dev nodemon

# En package.json, añadir:
"scripts": {
  "start": "node app.js",
  "dev": "nodemon app.js"
}

# Ejecutar
npm run dev

d




Comentarios

Entradas más populares de este blog

Cómo Iniciar un Proyecto Node.js

6-Middleware?