Tu primera experiencia con Node.js

1

驴D贸nde aprender backend con Node.js actualizado?

2

Todo lo que aprender谩s sobre backend con Node.js

3

驴Qu茅 es Node.js?

4

驴Qu茅 es Node.js y para qu茅 sirve?

5

Diferencias entre Node.js y JavaScript

6

Resumen: Diferencias Nodejs y Javascript

7

Instalaci贸n de Node.js

8

Arquitectura orientada a eventos

9

Node.js para la web

Manejo y uso de Streams con Node.js

10

Introducci贸n a streams

11

Readable y Writable streams

12

Duplex y Transforms streams

Uso de utilidades de Node.js

13

Sistema operativo y sistema de archivos

14

Administrar directorios y archivos

15

Consola, utilidades y debugging

16

Clusters y procesos hijos

Crea tu primer proyecto en Express.js

17

驴Qu茅 es Express.js y para qu茅 sirve?

18

Creando tu primer servidor con Express.js

19

Request y Response Objects

Aprende a crear un API con REST

20

Anatom铆a de una API Restful

21

Estructura de una pel铆cula con Moockaru

22

Implementando un CRUD en Express.js

23

M茅todos idempotentes del CRUD

24

Implementando una capa de servicios

C贸mo conectarse con librer铆as externas en Express.js

25

Creaci贸n de una BD en MongoAtlas

26

Conexi贸n a MongoAtlas una instancia de MongoDB

27

Conexi贸n con Robot3T y MongoDB Compass a una BD

28

Implementaci贸n de las acciones de MongoDB

29

Conexi贸n de nuestros servicios con MongoDB

Conoce como funcionan los Middleware en Express.js

30

驴Qu茅 es un middleware? Capa de manejo de errores usando un middleware

31

Manejo de errores as铆ncronos y s铆ncronos en Express

32

Capa de validaci贸n de datos usando un middleware

33

驴Qu茅 es Joi y Boom?

34

Implementando Boom

35

Implementando Joi

36

Probar la validaci贸n de nuestros endpoints

37

Middlewares populares en Express.js

Implementa tests en Node.js

38

Creaci贸n de tests para nuestros endpoints

39

Creaci贸n de tests para nuestros servicios

40

Creaci贸n de tests para nuestras utilidades

41

Agregando un comando para coverage

42

Debugging e inspect

Despliega tu primera aplicaci贸n en Express.js

43

Considerando las mejores pr谩cticas para el despliegue

44

Variables de entorno, CORS y HTTPS

45

驴C贸mo implementar una capa de manejo de cach茅?

46

驴C贸mo contener tu aplicaci贸n en Docker?

47

Despliegue en Now

Conclusiones

48

驴Qu茅 aprendiste en este curso?

Request y Response Objects

19/48

Lectura

El objeto req (Request) en Express representa el llamado HTTP y tiene diferentes propiedades del llamado, como la cadena de texto query (Query params), los par谩metros de la URL (URL params), el cuerpo (Body), los encabezados (HTTP headers), etc.

Para acceder al req basta con acceder al primer par谩metro de nuestros router handlers (router middleware) 贸 middleware.

Como por ejemplo, as铆 lo hemos visto siempre:

app.get("/user/:id", function(req, res) {
  res.send("user " + req.params.id);
});

Pero tambi茅n funcionaria sin problemas:

app.get("/user/:id", function(request, response) {
  response.send("user " + request.params.id);
});

Exploremos las propiedades m谩s importantes

req.body

Contiene los pares de llave-valor de los datos enviados en el cuerpo (body) del llamado (request). Por defecto es undefined pero es establecido cuando se usa alg煤n 鈥渂ody-parser鈥 middleware como body-parser y multer.

En Postman cuando hacemos un request y enviamos datos en la pesta帽a Body, estos middlewares son los que nos ayudan a entender el tipo de datos que vamos a recibir en el req.body.

Aqu铆 podemos ver como se pueden usar estos middlwares para establecer el valor del req.body:

const app = require("express")();
const bodyParser = require("body-parser");
const multer = require("multer");
const upload = multer(); // Para datos tipo multipart/form-data

app.use(bodyParser.json()); // Para datos tipo application/json
app.use(bodyParser.urlencoded({ extended: true })); // Para datos tipo application/x-www-form-urlencoded

app.post("/profile", upload.array(), function(req, res, next) {
  console.log(req.body);
  res.json(req.body);
});

M谩s informaci贸n sobre los diferentes formatos que puede tener el body: https://developer.mozilla.org/es/docs/Web/HTTP/Methods/POST

req.params

Esta propiedad contiene un objeto con las propiedades equivalentes a los par谩metros nombrados en la ruta. Por ejemplo, si tenemos una ruta de la forma /user/:name entonces la propiedad name est谩 disponible como req.params.name y all铆 podremos ver su valor. Supongamos que llamaramos a la ruta con /user/glrodasz, entonces el valor de req.params.name ser铆a glrodasz. Este objeto por defecto tiene el valor de un objeto vac铆o {}.

// GET /user/glrodasz
req.params.name;
// => "glrodasz"

req.query

Esta propiedad contiene un objeto con las propiedades equivalentes a las cadenas de texto query de la ruta. Si no hay ninguna cadena de texto query tendr谩 como valor por defecto un objeto vac铆o {}.

req.query.q;
// => "tobi ferret"

// GET /shoes?order=desc&shoe[color]=blue&shoe[type]=converse
req.query.order;
// => "desc"

req.query.shoe.color;
// => "blue"

req.query.shoe.type;
// => "converse"

M谩s informaci贸n sobre los query strings en: https://es.wikipedia.org/wiki/Query_string y https://tools.ietf.org/html/rfc3986#section-3.4

Response Object

El objeto res representa la respuesta HTTP que env铆a una aplicaci贸n en Express.

Para acceder al res basta con acceder al segundo par谩metro de nuestros router handlers (router middleware) o middleware.

Como por ejemplo as铆 lo hemos visto siempre:

app.get("/user/:id", function(req, res) {
  res.send("user " + req.params.id);
});

Pero tambi茅n funcionar铆a sin problemas:

app.get("/user/:id", function(request, response) {
  response.send("user " + request.params.id);
});

Exploremos los m茅todos m谩s comunes

res.end()

Finaliza el proceso de respuesta. Este m茅todo viene realmente del core de Node.js, espec铆ficamente del m茅todo response.end() de http.ServerResponse.

Se usa para finalizar el request r谩pidamente sin ning煤n dato. Si necesitas enviar datos se debe usar res.send() y res.json().

res.end();
res.status(404).end();

res.json()

Env铆a una respuesta JSON. Este m茅todo env铆a una respuesta (con el content-type correcto) y convierte el par谩metro enviado a una cadena de texto JSON haciendo uso de JSON.stringify().

El par谩metro puede ser cualquier tipo de JSON, incluido un objeto, un arreglo, una cadena de texto, un boolean, n煤mero, null y tambi茅n puede ser usado para convertir otros valores a JSON.

res.json(null);
res.json({ user: "tobi" });
res.status(500).json({ error: "message" });

res.send()

Env铆a una respuesta HTTP. El par谩metro body puede ser un objeto tipo Buffer, una cadena de texto, un objeto, o un arreglo. Por ejemplo:

res.send(Buffer.from("whoop"));
res.send({ some: "json" });
res.send("<p>some html</p>");
res.status(404).send("Sorry, we cannot find that!");
res.status(500).send({ error: "something blew up" });

Aportes 119

Preguntas 1

Ordenar por:

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

Uy, yo creo que esta secci贸n amerita una explicaci贸n mejor. Creo que queda muy t茅cnico y es muy f谩cil perderse en esta explicaci贸n. Adem谩s hablan de los middlware como si fuera un tema ya visto.

Esta clase es realmente sencilla:

El request trae todos los datos del cliente hacia el servidor (client => request => server).
El response se usa para cargar la respuesta que se devuelve al cliente (server => response => client)

Aqu铆 mi soluci贸n.

b谩sicamente no est谩 nada explicado, habla de cosas que no ha mencionado con anterioridad, como middleware, request.params, req.body, todo explicado muy minimo y sin ejemplos practicos, termino sin entender nada esta seccion.

Tengo la costumbre de que aunque sea un programa sencillo cuyo input controle, le meto validaciones

const express = require('express');

const app = express();

const { config } = require('./config/index');

app.get('/birthday', function (req, res) {
  if (req.query == {}) {
    res.send(`
      <h1> Debes enviar tu fecha de nacimiento por GET con los siguientes parametros</h1>
      <ul>
      <li> day</li>
      <li> month</li>
      <li> year</li>
      </ul>
    `);
  }

  const { year } = req.query;

  if (year == undefined) {
    res.send(`
      <h1> Al menos envia el a帽o ?year=1900</h1>
     
    `);
  } else if (!Number.isInteger(year) && year < 1000) {
    res.send(`
      <h1> El parametro a帽o debe ser un n煤mero y debe ser de 4 digitos por ejemplo ?year=1900</h1>
     
    `);
  }

  let result =
    year % 4 == 0 && (year % 100 != 0 || year % 400 == 0) ? true : false;

  const anoB = result ? 'Si' : 'NO';

  res.send(`<h1> Tu a帽o de nacimiento ${anoB} es bisiesto</h1>`);
});

app.get('/json', function (req, res) {
  res.json({ hello: 'world' });
});

app.listen(config.port, function () {
  console.log(`Listening localhost:${config.port}`);
});```

Peque帽o resumen y explicaci贸n para aquellos que no est谩n familiarizados con las peticiones y respuestas HTTP:
Un servidor/API en general se encarga de 2 cosas: recibir peticiones (req | request) desde el cliente y devolver una respuesta (res | response) al mismo cliente.

  • Un middleware es una herramienta que va a recibir las peticiones en formatos HTML, escritos de forma un poco compleja (incluso encriptados para conexiones HTTPS) y las va a transformar en objetos faciles de manejar (req y res) que recibimos en nuestro c贸digo. Adem谩s, el middleware tambi茅n va a tomar nuestra respuesta (ejemplo: res.send(鈥淗ello鈥)) y la va a transformar en respuestas HTML mas complejas y devolverlas al navegador. En resumen, el middleware hace una tarea de parse para simplificar el manejo de respuestas y peticiones HTML.

  • Peticiones (req | request):
    Principalmente hay 2 tipos de peticiones: GET y POST
    GET es la mas simple y se ejecuta cada vez que intentamos acceder a un URL por ejemplo:
    https://platzi.com/home
    Alli, el navegador hace una petici贸n GET de la ruta /home
    Las peticiones GET tambi茅n pueden contener variables por ejemplo en localhost/user/?id=1 se va a hacer una petici贸n a la ruta /user/ enviando la variable id = 1.

    POST es mas compleja y permite enviar datos desde el cliente hasta el servidor de diferentes tipos, por ejemplo texto plano, JSON, binarios, etc. Este tipo de petici贸n contiene cabeceras (Headers) que permiten decirle al middleware el tipo de datos que tiene que tratar para hacerlo llegar a nuestra aplicaci贸n.

  • Respuestas (res | response):
    Es la respuesta que va a ser enviada desde el servidor hasta el cliente. Esta respuesta puede ser un contenido html, un binario, un JSON, etc. Por ejemplo cuando hacemos el GET de https://platzi.com/home, la respuesta va a contener el html que va a ser cargado en el navegador para visualizar el home de platzi. Al igual que cuando accedemos a un curso, hay respuestas de tipo binario que se hacen para cargar los videos. etc.

Espero este resumen les ayude un poco dado que estos temas son un poco mas profundos.

Yo decidi hacerlo con el metodo post para poder tener un formulario. Aca esta mi solucion:

<const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const { config } = require('./config/index');
app.use(bodyParser.urlencoded({extended:true}));

const formulario =
  '<h1>Ingrese un a帽o</h1>' +
  '<form method="post" action="/bisiesto">' +
  '<input type="text" name="anioIngresado">' +
  '<input type="submit" value="Enviar">' +
  '</form>';

app.get('/', (request, response) => {
  response.send(
    '<html><body>' +
    formulario + 
    '</body></html>'
  );
});

const esBisiesto = (anio) => {
  let verificacionAnio = (((anio % 4 == 0) && (anio % 100 != 0)) || (anio % 400 == 0)) ? 1 : 0;
  if (! verificacionAnio){
    return false;
  }
  else{
    return true;
  }
}

app.post('/bisiesto', (request, response) => {
  let anio = request.body.anioIngresado;
  let resultado = '';
  if(esBisiesto(anio) == true){
    resultado = 'es bisiesto';
  }
  else{
    resultado = 'no es bisiesto';
  }

  response.send(
    '<html><body>' +
    '<p>El a帽o ingresado ' + resultado + '</p>'
  );
});

app.listen(config.port, () => {
  console.log(`Live at http://localhost:${config.port}`);
})>

Mi soluci贸n al reto 馃槃

Aqu铆 mi soluci贸n

Bueno, aqu铆 mi soluci贸n al reto, pase todo directo a un if

app.get('/year/:year', function(req, res) {
    let y = req.params.year;
    if (y % 4 === 0 && y % 100 !== 0 || y % 400 === 0) {
        res.send('True');
    } else {
        res.send('False');
    }
})

Primera solucion

Mejorando el codigo

Explicacion de bisiesto

Estuve algunos videos adelante, y ahora repitiendo este contenido ya es mas claro todo.

  • home

  • Respuesta

  • Respuesta

  • Respuesta

  • messges.js

  • year.js

  • index.js

  • head all files html

  • body index.html

  • body leap.html

Ey! Tengo un super un resumen con una explicacion y ejercicio resuelto de manera entendible que les encantara!

Resumen: METODOS. GET => se ejecuta cuando el cliente requiere algo de nuestra pagina, basicamente cuando requiere datos. Por lo tanto el metodo GET le dara a el cliente esos mismos datos que el requiere.

POST => nos sirve para guardar/tomar recursos externos(del cliente) y guardarlos en el back-end. ejemplo el cliente nos da su fecha de nacimiento en un form, esto lo guardamos en el back-end y lo trabajamos de la manera que queramos.

continuemos con otro apartado-----------------------

Bien, en mi opinion el req.body es el mas interesante, ya que podemos obtener la data del body y con esto trabajar los datos en nuestro back-end.

bien, y si llevamos esta informacion a un campo real?

const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const { config } = require('./config/index');
app.use(bodyParser.urlencoded({extended:true}));

const formulario = 

    '<h1> Calculadora de edad </h1>' +
    '<p> Ingresera su fecha de nacimiento y nuestro algoritmo le dira cuantos a帽os posee actualmente</p>' +
    '<form method="post" action="/edadActual">' +
    '<input type="number" name="anioIngresado">' +
    '<input type="submit" submit value="Enviar">'+
    '</form>';


app.get('/', (req,res) => {
    res.send(
        '<html><body>' +
        formulario +
        '</body></html>'
    );
});

app.post('/edadActual', (req,res) => {
    let a帽os = req.body.anioIngresado;
    let edadActual = 2021 - a帽os;

    res.send(
        '<html><body>' +
        '<h1>Calculemos Su Edad</h1>'+
        `<p>Entonces si naciste en ${a帽os} y estamos en 2021, por lo tanto tu edad Actual es: </p>`+
        edadActual +
        '</body></html>'
    );
});



app.listen(config.port, () => {
    console.log(`Live at https://localhost:${config.port}`);
  })

Hola como estan!! Encontre un video que aclara un MONTON.
https://youtu.be/0t93qDkGcB0, escribanle el https, ya que se lo saque.

index.js

<code>
const express = require('express');
const app = express();
const { config } = require('./config/index');
const {esBisiesto} = require('./Modulos/bisiesto');

app.post('/:year', (req, res) => {
    res.send(esBisiesto(req.params.year));
});

app.listen(config.port, () => {
  console.log(`Listening http://localhost:${config.port}`);
});
</code>

M贸dulo

<code>
const esBisiesto = (year) => {
  if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
    return `El ${year} es bisiesto`;
  } else {
    return `El ${year} no es bisiesto`;
  }
};

module.exports = {
  esBisiesto,
};
</code>

Mi versi贸n del reto. Todav铆a no se bien como manejar el html dentro del res.send(), me gustaria entender como mandar stream al res.send
Seguro m谩s adelante lo aprenderemos o habr谩 que investigar.

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

const { config } = require('./config/index');

app.get('/', function (req, res) {
  const text = `
	<h1> Verificador de a帽os biciestos </h1>
	<p> Para verificar si un a帽o es bisiesto
	debes accerder a la ruta:</p>
	<p style="text-align:center; font-size:30px">127.0.0.1:${config.port}/bisiesto/:a帽o </p>`;

  res.send(text);
});
app.get('/bisiesto/:year', function (req, res) {
  const year = req.params.year;
  let respuesta = '';
  if (year % 4 === 0) {
    respuesta = 'si';
  } else {
    respuesta = 'no';
  }
  const text = `<h1> Respuesta </h1>
		<p> El a帽o <strong>${req.params.year} </strong> ${respuesta} es a帽o bisiesto </p>
		`;
  res.send(text);
});

app.listen(config.port, function () {
  console.log(`Escuchando el puerto ${config.port}`);
});

Challenge completado 馃

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

const { config } = require('./config/index');

app.get('/', function (req, res) {
  res.send('Envia un a帽o y comprobaremos si es o no un a帽o bisiesto');
});

app.get('/:year', function (req, res) {
  const year = parseInt(req.params.year);
  console.log(year);
  if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {
    res.send(`${year} es un a帽o bisiesto`);
  } else {
    res.send(`${year} no  es un a帽o bisiesto`);
  }
});

app.listen(config.port, function () {
  console.log(`Listening to port https://localhost:${config.port}`);
});

muy interesante como maneja las peticiones Node.js

Mi soluci贸n:

function isLeap(anio) {
  return (anio % 4 == 0 && anio % 100 != 0) || anio % 400 == 0 ? 1 : 0;
}

app.get('/bisiesto/:anio', (req, res) => {
  const anio = req.params.anio;
  res.json({
    message: +anio + ' is leap-year? ' + (isLeap(anio) ? 'Yes' : 'No'),
    result: isLeap(anio),
  });
});

Muy mal que esto se ponga como texto y no en un video explic谩ndolo

const express = require('express');

const app = express();

const { config } = require('./config/index');

app.get('/', function(req, res) {
    res.send('hello world');
});

app.get('/json', function(req, res) {
    res.json({ hello: 'world' });
});

app.get('/:year', function(req, res) {
    const year = parseInt(req.params.year);
    if((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0){
        res.send(`${year} es bisiesto`);
    }else{
        res.send(`${year} no es bisiesto`);
    }
});

app.listen(config.port, function() {
    console.log(`Listening http://localhost:${config.port}`);    
});

Lo hab铆a resuelto en mi ejercicio anterior, pero vi que se pod铆an usar algunas instrucciones de deconstructuring y ternarios y lo hice un poco m谩s simple:

app.get('/anyo-bisiesto-checker', function (req, res) {
  let anyo = req.query.anyo;
  let anyoBisiesto = (anyo % 4 == 0 && anyo % 100 != 0) || anyo % 400 == 0;
  res.send(`El a帽o ${anyoBisiesto ? 'es bisiesto' : 'no es bisiesto'}.`);
});
app.get('/challenge/:year', function (req, res) {
    let { year } = req.params;
    res.json({ year: `${year}`, result: `${((year % 4 === 0 && year !== 0) || year % 400 === 0) ? 'si es bisiesto' : 'no es bisiesto'}` });
});

Adem谩s de body-parser tambi茅n se puede hacer 鈥渘ativamente鈥 con Express as铆:

// Para datos tipo application/json
app.use(express.json());

// Para datos de tipo application/x-www-form-urlencoded
app.use(express.urlencoded({extended: true}));

// Para datos de tipo text/plane
app.use(express.text());

Estuvo sencillo para lo que se ped铆a, mi soluci贸n fue:

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

const { config } = require('./config');
app.set('port', config.port);

app.get('/bisiesto/:id', (req, res) => {
    const { id } = req.params;
    if (id % 4 == 0)
        return res.json({ bisiesto: true, message: "Es a帽o bisiesto" })
    else
        return res.json({ bisiesto: false ,message:"No es a帽o bisiesto"})
})

app.get('/', (req, res) => {
    return res.send('Hello')
})
app.get('/json', (req, res) => {
    return res.json({ hello: "world" })
})
app.listen(app.get('port'), (req, res) => {
    console.log(`Server on  http://localhost:${app.get('port')}`);
})

Reto completado:

const express = require("express");
const app = express();
const { config } = require("./config/index");

app.get("/reto/:year", (request, response) => {
    const year = request.params.year;

    const bisiesto = () => {
        if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {
            response.send(`${year} es Bisiesto`);
        } else {
            response.send(`${year} no es Bisiesto`);
        }
    }

    function validate() {
        isNaN(year) === true ? response.send("Introduce una fecha valida") : bisiesto();
    }

    validate();
});

app.listen(config.port, () => {
    console.log(`Escuchando ${config.port}`)
})

Despu茅s de ver las respuestas de los dem谩s me siento tramposo al usar 鈥渕oment鈥 para resolver el problema.

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

const { config } = require('../config/index');

app.get('/:year', function(req, res) {
    const year = req.params.year;
    if (moment([year]).isLeapYear()) {
        res.send('El a帽o ' + year + ' es bisiesto');
    }

    res.send('El a帽o ' + year + ' no es bisiesto');
});

app.listen(config.port, function() {
    console.log(`Listening https://localhost:${config.port}`)
});

Aqu铆 dejo mi soluci贸n al reto:

app.get('/leap/:year', (req, res) => {
    let year = req.params.year;
    
    console.log

    if (year.length == 4) {
        if ( (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) == false ) {
            res.send(`${year} no es un a帽o bisiesto`);
        }
        res.send(`${year} es un a帽o bisiesto`);
    } else {
        res.send('Ingresa un a帽o con 4 digitos.')
    }
})```

No fu茅 la soluci贸n mas elegante pero cumpli贸 su cometido.

const express = require("express");
const app = express();

const { config } = require("./config/index");

function evalYear(year) {
  let isLeap = false;

  if (year % 4 == 0) {
    console.log("The year %d is divisible by 4", year);
    if (year % 100 == 0) {
      console.log("The year %d is divisible by 100", year);
      if (year % 400 == 0) {
        console.log("The year %d is divisible by 400", year);
        console.log("The year %d is a Leap year", year);
        return (isLeap = true);
      } else {
        console.log(
          "The year %d is divisible by 4 and 100 but not by 400",
          year
        );
      }
    } else {
      console.log("The year %d is divisible by 4 but not by 100");
      return (isLeap = true);
    }
  } else {
    console.log("The %d is not a Leap Year", year);
    return isLeap;
  }
}


app.get("/", function (req, res) {

  console.log(req.params);
  res.send("Hello world");
});

app.get("/year/:year", function (req, res) {
  let year = Number(req.params.year);

  if (evalYear(year) == true) {
    res.send(`${year} is a Leap year`);
  } else {
    res.send(`${year} is not a Leap year`);
  }
});


app.listen(config.port, function () {
  console.log("listening on port: " + config.port);
});

Espero esta imagen les sirva para entender mejor los query strings.

驴Qu茅 es un middleware?

En pocas palabras, un middleware permite conectar dos aplicaciones para el intercambio de datos. Un ejemplo de esto son las bases de datos. Otro tipo de middleware pueden ser las APIs.

mi codigo, simplificando los codigos de los comentarios:

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

const { config } = require('./config/index');

app.get('/anio:year', (req, res) => {
  let year = req.params.year;

  if (
    (year.length === 4 && year % 4 === 0) ||
    year % 100 === 0 ||
    year % 400 === 0
  ) {
    res.json({
      message: `El a帽o que ingreso fue ${year}`,
      isBicies: `Es a帽o es bisiesto es decir tiene 365 dias`,
    });
  } else {
    res.json({
      message: `El a帽o enviado es ${year} y no es un a帽o valido`,
    });
  }
});

app.listen(config.port, () => {
  console.log(`Listening in ${config.port}`);
});

Hola como estan? Encontre un video super simple que aclara un MONTON. https://youtu.be/0t93qDkGcB0

Este es el c贸digo de mi reto:

const express = require('express')
const app = express()
const moment = require('moment')

const { config } = require('./config/index')

app.get('/', function (req, res) {
  res.send('Hello world')
})

app.get('/json', function (req, res) {
  res.json({Hello: 'world'})
})

app.get('/bisiesto', function (req, res) {
  res.json(isBisiesto(req.query.date))
})

app.listen(config.port, function () {
  console.log(`Listening htttp://localhost:${config.port}`);
})

function isBisiesto(dateString) {
  if (moment(dateString).isValid()) {
    let year = moment(dateString).format('yyyy')
    if (parseInt(year, 10) % 4 == 0) {
      return 'A帽o bisiesto'
    } else {
      return 'A帽o normal (NO bisiesto)'
    }
  } else {
    return 'Error en el formato de la fecha'
  }  
  return
}

req (servidor) y res (cliente)

let year; 
let year = year % 4 == 0 ? "El a帽o es Bisiesto" : "El a帽o no es Bisiesto";
year = 2000; // req.body
"El a帽o es Bisiesto" // res.send
year = 2001; // req.body // req.body
"El a帽o no es Bisiesto" // res.send

Comparto mi challenge:

const express = require('express');

const app = express();

app.get('/year/:year', (req, res) => {
  const { year } = req.params;

  if (isNaN(year)) {
    res.status('400').json({ error: 'Year must be a number' });
  }

  if (!/^\d{1,4}$/.test(year)) {
    res
      .status('400')
      .json({ error: 'Year size must be between 1 and 4 characters' });
  }

  if (!(year % 4) && year % 100 != 0) {
    res.json({ message: `Year ${year} is bisiesto 馃挌` });
  }

  if (!(year % 400)) {
    res.json({ message: `Year ${year} is bisiesto 馃挌` });
  }

  res.json({ message: `Year ${year} is not bisiesto 馃挃` });
});
app.listen(3000, function () {
  console.log(`Listening on port 3000`);
});

app.get('/:year', function(req, res) {
    const year = parseInt(req.params.year);
    console.log('A帽o',  year)
    if (isLeapYear(year)) {
        res.send({ year: 'is Leap Year'})
    } else {
        res.send({ year: 'Normal Year'})
    }
});

const isLeapYear = (year) => {
    //Cuando no existe el 29 de febrero autom谩ticamente new Date crea 1 de marzo, si lo comparamos contra 1 de marzo podemos saber si es o no bisiesto
    return (new Date(year+'-02-29')).toDateString() !== (new Date(year+'-03-01')).toDateString()
  };

Muy buena explicaci贸n de res y req

app.get('/bisiesto/', function (req, res) {
    res.send('Ejemplo para saber si el a帽o ingresado es bisiesto, favor ingresar el parametro anio a travez de la URL');
})
app.get('/bisiesto/:anio', function (req, res) {
    try {
        const anio = parseInt(req.params.anio);
        if (!anio || isNaN(anio) || typeof anio !== 'number' || !Number.isInteger(anio) || anio <= 0)
            return res.send(`El a帽o ingresado no cumple con los requisitos para ser evaluado`);
        let mensajeBisiesto = `es`;
        if (anio % 4 !== 0)
            mensajeBisiesto = `no es`;
        return res.send(`El a帽o ${anio} ${mensajeBisiesto} bisiesto`);
    } catch (error) {
        console.log(error);
    }
});

Quiz谩 innecesario utilizar el modulo leap-year, pero aqu铆 est谩 mi aporte 馃槃.

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

const leap_year = require('leap-year');

const {config} = require('./config/index');

app.get('/isLeap:year', (req,res)=>{
    res.send(leap_year(parseInt(req.params.year.slice(1))));
});

app.listen((config.port), ()=>{
    console.log(`Servidor en el puerto ${config.port}`);
});

No entendi muy bien .end() pens茅 que por naturaleza se cerraba el proceso sin necesidad de .end()

Les comparto mi soluci贸n

const express = require("express");
const APP = express();
const PORT = 3000;
const isLeapYear = (year) => (year % 4 === 0 && year % 100 > 0) || (year % 400 === 0);

APP.get("/year/:year?", (request, response) => {
    let { year = 0 } = request.params;
    let status = 404;
    let msg = "Se tiene que propocionar un a帽o";
    year = parseInt(year, 10);
    const IS_LEAP_YEAR = isLeapYear(year);
    if (IS_LEAP_YEAR && year > 0) {
        status = 200;
        msg = IS_LEAP_YEAR ? "366 es " : "365 no es";
        msg = `El a帽o ${year} tiene ${msg} biciesto`;
    }
    response.status(status).send(msg);
});

APP.listen(PORT, () => {
    console.log(`Estoy corriendo en el puerto ${PORT}`);
});

app.post('/leap-year/:year', function(req, res) { const year = req.params.year if(year % 4 === 0 && year % 100 !== 0 || year % 400 === 0 ){ res.send(Year ${year} is leap-year); } else { res.send(Year ${year} is not leap-year`);
}

})`

Esta es mi soluci贸n:

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

const { config } = require('./config/index')

function isLeap(year) {
    return ((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)
}

app.get('/', function(req, res) {
    res.send('hello world')
})

app.get('/json', function(req, res) {
    res.json({ hello: 'world' })
})

app.get('/isleap/:year', function(req, res) {
    const year = req.params.year
    const esBisiesto = isLeap(year)
    if (esBisiesto) {
        res.send(`El a帽o ${year} es bisiesto`)
    } else {
        res.send(`El a帽o ${year} no es bisiesto`)
    }
})


My solution:


const express = require('express');
const app = express();
const { config } = require('./config/index');

const isLeap = (arg) => arg % 100 === 0 ? arg % 400 === 0 : arg % 4 === 0;

app.get('/leap:year', (req, res) => {
  let modifier = '';
  let query = parseInt(req.params.year.slice(1));
  let now = parseInt(new Date().getFullYear());

  if(query < now){
    isLeap(query) ? modifier = `was` : modifier = `wasn't`;
  }else if(query === now){
    isLeap(query) ? modifier = `is` : modifier = `isn't`;
  }else{
    isLeap(query) ? modifier = `will be` : modifier = `won't be`;
  }

  res.send(`${query} ${modifier} leap-year`);
});

app.listen(config.port, () => {
  console.log('====================================');
  console.log(`Listening :${config.port}`);
  console.log('====================================');
});

el c贸digo del reto:

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

const { config } = require('./config/index');

app.get('/:year', function(req, res) {
  const anio = parseInt(req.params.year);
  if (isNaN(anio)) {
    res.send('Se necesita un n煤mero valido');
  }

  if (anio % 4 === 0 && (anio % 100 !== 0 || anio % 400 === 0)) {
    res.send(`El anio: ${anio}, es bisiesto`);
  } else {
    res.send(`El anio: ${anio}, no es bisiesto`);
  }
});

app.listen(config.port, function() {
  console.log(`Listening http://localhost:${config.port}`);
});

Es recomendable seguir usando ExpressJS o un Framework como Sails.JS

Reto Completado!

En Windows, agregar 鈥set DEBUG=app:* **&**nodemon index鈥 para ejecutar sin problemas npm run dev

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

const moment = require('moment');

const { config } = require('./config/index');

app.get('/', function(req, res){
    res.send("hello word!");
});

app.get('/json', function(req, res){
    res.json({hello : 'word'});
});

app.get('/bisiesto/:anio', function(req, res){
    let anio = req.params.anio;
    res.json({anio:req.params.anio, esBisiesto: moment([anio]).isLeapYear()});
});

app.listen(config.port, function(){
    console.log(`Escucahndo http://localhost:${config.port}`);
});

Este resumen me fue de mucha ayuda, al detallar cada uno de los m茅todos, que usan tanto el request y el response, hace que todo sea mas entendible, por el proceso que lleva el servidor.

mi version

const express = require("express");
const app = express();

const { config } = require("./config/index");

app.get("/", function(req, res) {
  res.send("hello world");
});

app.get("/json", function(req, res) {
  res.send({ hello: "world" });
});

app.get("/bisiesto/:year", function(req, res) {
  let year = req.params.year;
  if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) {
    res.send(`${req.params.year} is bisiesto`);
  } else {
    res.send(`${req.params.year} isn't bisiesto`);
  }
});

app.listen(config.port, function() {
  console.log(`listening http://localhost:${config.port}`);
});

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

const { config } = require('./config/index');

app.get('/', ( req, res ) => {
   res.send('Hello World');
});


app.get('/json', ( req, res ) => {
   res.json({ hello: 'world' });
});

app.get('/bisiesto/:year', ( req, res ) => {
   let year = req.params.year;

   let isBisiesto = ((year % 4 === 0) && (year % 100 !== 0 )) || (year % 400 === 0);

   isBisiesto ? res.send(`${ year } es bisiesto`) : res.send(`${ year } no es bisiesto`);
   
});

app.listen(config.port, () => {
   console.log(`Listening http://localhost:${config.port}`);
});
app.get('/bisiesto/:anio', (req, res) => {
  let anio = req.params.anio;

  if (anio % 4 == 0 && anio % 100 != 0) {
    res.send('El a帽o es bisiesto!');
  } else {
    res.send('El a帽o no es bisiesto :(');
  }
});

Reto terminado:

app.get('/bisiesto/:year', function (req, res) {
  const year = parseInt(req.params.year)
  if (!isNaN(year)) {
    res.json({ 'Bisiesto': year % 4 === 0 })
  } else {
    res.send('Este no es un a帽o')
  }
})
const express = require('express')
const app = express()

const { config } = require('./config/index')

app.get('/', (req, res) => {
  res.send('Hello world')
})

app.get('/json', (req, res) => {
  res.json({hello: 'world'})
})

app.get('/year/:year', (req, res) => {
  const { year } = req.params
  const leapYear =
    (year % 4 === 0 && (year % 100 !== 0 || year % 400 == 0)) ?
      "is leap-year" :
      "is not leap-year"
  res.send(`The ${year} ${leapYear} `)
} )

app.listen(config.port, () => {
  console.log(`listening http://localhost:${config.port}`)
})```
const express = require('express');
const app = express();

function bisiesto(year) {
  const isLeap = !(new Date(year, 1, 29).getMonth() - 1)
  if (isLeap) {
    return 'a帽o bisiesto'
  }
  return 'a帽o no bisiesto'
}

app.get('/params/:name', function (req, res) {
  res.send(`El a帽o ${req.params.name} es un ${bisiesto(req.params.name)}`);
});

app.listen('3001', function () {
  console.log('Listening to port 3001');
});```
app.get('/bisiesto/:year', (req, res) => {
    const year = req.params.year;

    if ((year % 4 === 0  && year % 100 !== 0) || year % 400 === 0) {
        return res.send("Es bisiesto");
    }

    return res.send("No es bisiesto");
});```

Reto:

app.post("/date/:year", (req, res) => {
  console.log(req.params.year);
  let leap = false;
  
  if ( (req.params.year % 4) === 0 ) {
    leap = true;
  }

  res.send({ leap_year: leap.toString() });
});

Reto:

const express = require('express');

const app = express();

const { config } = require('./config/index');

app.get('/', (req, res) => {
    res.send('Hello World');
});

app.get('/json', (req, res) => {
    res.json({hello: 'world'});
});

app.get('/leap-year/:year', (req, res) => {
    const year = parseInt(req.params.year);
    const leapYear = (year) => {
        return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
    }

    const isLeapYear = leapYear(year);
    const message = isLeapYear ? 'Yes, it\'s a leap-year' : 'Nop, it\'s not a leap-year';

    res.send({isLeapYear: isLeapYear, year: year, message: message});

})

app.listen(config.port, () => {
    console.log(`Listening in http://localhost:${config.port}`);
});

Solo agregen el codigo al index y ejecutar en el navegado /bisieto/id(el anio)

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

const { config } = require('./config/index');

app.get('/', function (req, res) {
  res.send('Hello Word');
});
app.get('/bisieto/:id', function (req, res) {
  //parametro de calculo bisieto
  const isLeapYear = (year) => {
    year = year instanceof Date ? year.getFullYear() : year;
    return !(new Date(year, 1, 29).getMonth() - 1);
  };
  //Se le pasa id con req.params.id)
  const IsBistiento = isLeapYear(parseInt(req.params.id));
  
  //ternario
  const mensaje = IsBistiento
    ? '<h1>es bisieto</h1>'
    : '<h1>no es bisieto</h1>';
  res.send(mensaje);
});

app.get('/json', function (req, res) {
  res.send({ hello: 'Hola' });
});

app.listen(config.port, function () {
  // eslint-disable-next-line no-console
  console.log('Todo bien');
});

const express = require('express');
const app = express();
const { config } = require('./config/index');

app.get('/:amo', (req, res) => {
    const amo = parseInt(req.params.amo);
    if(amo){
        if ((((amo % 4 == 0)
            && (amo % 100 != 0))
            || (amo % 400 == 0))
        )
            res.send(`El a帽o ${amo} es bisiesto!`)
        else
            res.send(`El a帽o ${req.params.amo} NO es bisiesto`);
    }else{
        res.send(`Dame un a帽o en la url en 4 digitos`);
    }
});

app.listen(config.port, () =>{
    console.log(`Corriendo en http://localhost:${config.port}`)
})```
app.get("/ano/:date" , (req,res)=>{
    const date = req.params.date;
    if(date % 4 === 0){
        return res.send("es biciesto")
    }else{
        res.send("no es biciesto")
    }
})

genial!

Soluci贸n al reto

app.get('/:year', (req, res) => {
    const a帽o = parseInt(req.params.year);
    (((a帽o % 4 == 0) && (a帽o % 100 != 0 )) || (a帽o % 400 == 0)) ? res.send(`El a帽o ${a帽o} es bisiesto`) : res.send(`El a帽o ${a帽o} no es bisiesto`) 
});

Mi soluci贸n:

app.get("/anio/:year", (req, res) => res.json({ leap: req.params.year % 4 === 0 && true}) );
const express = require('express');

const app = express();

const {config} = require('./config/index.js');


app.get('/anio/:year', function(req, res){
    let year = req.params.year;
    res.send(bisiesto(year)).end();
});

const bisiesto = (year) => {
    if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0){
        return 'el a帽o es bisiesto';
    } else {
        return 'el a帽o no es bisiesto'
    }
}

app.listen(config.port);

console.log(`Escuchando en http://localhost:${config.port}`);```
app.post('/', function (req, res) {
  const body = req.body;
  const year = body.year;

  if (year % 4 == 0) {
    res.json({
      leap_year: true,
    });
  } else {
    res.json({
      leap_year: false,
    });
  }
});

Reto realizado

app.get('/anno/:year', (req,res)=>{
    const year = req.params.year
    const msg = (year % 4 ==0)
        ? `El a帽o ${year} es un a帽o bisiesto`
        : `El a帽o ${year} es un a帽o normal`
    res.send(msg)
})

app.get('/validate/:year', function (req, res) {
    let year = req.params.year

    if (year % 4 === 0 && year % 100 === 0 && year % 400 === 0 || year % 4 === 0 && year % 400 === 0) {
        res.send(`El a帽o ${year} si es bisiesto`)
    } else  {
        res.send(`El a帽o ${year} no es bisiesto`)
    }
})```

Mi solucion al reto:

const express = require('express');
const app = express();
const { config } = require('./config/index.js');

function esBisiesto(year) {

  return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) ? true : false;

}

app.post('/biciesto/:year', function (request, response) {
  let message;

  if (esBisiesto(parseInt(request.params.year))) {
    message = "Es biciesto";
  } else {
    message = "No es biciesto";
  }

  response.send(message);
});

Tambien podemos agregar expresiones regulares a los par谩metros de las rutas en express, en este caso para solo permitir haga el match si el par谩metro es num茅rico:

app.get('/:year(\\d*\\d*)', (req, res) => {
	
});

saludos,

Esta es mi soluci贸n al reto

app.get('/year/:year', function(req, res){
    let a帽o = req.params.year;
    let esBiciesto = a帽o % 4 === 0 && (a帽o % 100 !== 0 || a帽o % 400 === 0);
    res.send(`El a帽o ${a帽o} es ${esBiciesto ? 'biciesto' : 'no biciesto'}`);
});

RETO:

const express = require('express')
const app = express()
const { config } = require('./config/index')

app.get('/comprobar/:year', (req, res) => {
    req.params.year % 4 === 0
        ? res.status(200).send(`El a帽o ${req.params.year} es bisiesto`)
        : res.status(200).send(`El a帽o ${req.params.year} no es bisiesto`)
})

app.listen(config.port, () => {
    console.log(`Listening http://localhost:${config.port}`)
})
const express = require('express');
const app = express();

const { config } = require('./config/index');
const { port } = config;

app.post("/profile", function(req, res) {
    let body = [];
    req
    .on('data', (data) => {
        body.push(data);
    })
    .on('end', () => {
        body = Buffer.concat(body).toString();
        let bisiesto = body % 4 == 0 && body % 100 != 0 || body % 400 == 0;
        bisiesto ? res.send('A帽o Bisiesto') : res.send('No es un a帽o Bisiesto');
        res.end();
    });
});

app.listen(port, function() {
    console.info(`Listening in port: http://localhost:${port}`);
});```
const express = require('express');
const app = express();

const { config } = require('./config/index');

app.get('/', (req, res) => {
  res.send('Welcome to home');
});

app.get('/calc/:year', (req, res) => {
  let { year } = req.params;

  let isValid = (year % 4 === 0 && year !== 0) || year % 400 === 0;
  res.send(`${year} ${isValid ? 'is prime' : 'no yet'}`);
});
app.get('/user/:name', (req, res) => {
  res.send(`user: ${req.params.name}`);
  res.status(404).end('not found');
});

app.listen(config.port, () => {
  console.log(`listen on http://localhost:${config.port}`);
});

Me faltaron mas comprobaciones, pero quedo

const express = require('express');

app = express();

app.get('/', (req, res) => {
    res.send('Hola mundo')
})

app.get("/year/:number", (req, res) =>{
    const year = req.params.number;

    if (year % 4 === 0) {
        res.send(`El ano ${year} es bisiesto`)
    } else{
        res.send(`El ano ${year} no es bisiesto`)
    }
    
    
})

app.listen(3000, () => {
    console.log('Listening in port 3000')
})```

Desaf铆o usando moment() y req.params

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

const { config } = require('./config/index.js');

app.get('/', function (req, res) {

  if (req.query.year) {
    if (moment(req.query.year).isLeapYear()){
        res.send('Si, es a帽o bisiesto')
    } else {
      res.send('No, no es a帽o bisiesto')
    }
  }
  res.send('hello world');
});

app.get('/json', function (req, res) {
  res.json({hello: 'world'});
});



app.listen(config.port, function() {
  console.log(`listening to port ${config.port} on localhost`)
});

No se me hizo nada f谩cil este reto

app.get('/bisiesto/:year', (req, res) => {
  let year = req.params.year;
  res.send(year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)
    ? 'A帽o bisiesto'
    : 'No es a帽o bisiesto'
  );
})

aqu铆 el reto 馃憣鈿★笍

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

const { config } = require('./config/index.js');

function bisiesto(year) {
    if (year % 4 === 0) {
        return `${year} es bisiesto`;
    } else {
        return `${year} no es bisiesto`;
    }
}

app.get('/', function (req, res) {
    res.send('Hello world');
});

app.get('/year/:year', function (req, res) {
    res.send(bisiesto(req.params.year));
});

app.listen(config.port, function () {
    console.log(`Listening in https://localhost:${config.port}`);
});

Les comparto mi solucion

app.get('/date/:date', (req, res) => {

    if((req.params.date).split('-').length < 3) {
        res.json({"error": "Bad date structure"});
        return
    } 

    if (moment(req.params.date, "DD-MM-YYYY").isLeapYear()) {
        res.json({"data": true});
        res.end();
    } else {
        res.json({"data": false});
        res.end();
    }
});

Aqu铆 mi soluci贸n

app.get('/challenge/:year', (req, res) => {
  res.send(isLeap(req.params.year))
})

const isLeap = (year) => (year % 4  === 0 && (year % 100 !== 0 || year % 400 === 0 )) ? 'Es bisiesto' : 'No es bisiesto'
const express = require('express')
const app = express()

app.get( '/:year', ( req, res ) => {
    let BISIESTO = req.params.year%4
    BISIESTO === 0 ? BISIESTO = 'Es bisiesto!' : BISIESTO = 'No es bisiesto :('
    res.send(`Interesante imaginate que ese a帽o... ${ BISIESTO }`)
} )

app.listen(3000, () => {
    console.log(`Listening in the port 3000`)
})

Here we go!!

El challenge

const express = require('express')
const app = express();
const config = require('./config/index')

app.get('/:year',(req,res)=>{
    const year = req.params.year
    res.send(year%4===0 
        ? `el a帽o ${year} es bisiesto` 
        : `el a帽o ${year} no es bisiesto`)
})

app.listen(config.port)```

Esta es mi humilde soluci贸n al challenge:

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

const { config } = require('./config/index');

app.get('/:year', (req, res) => {
  const year = req.params.year;
  const leapYear = isLeapYear(year);
  const message = `El a帽o ${ year } ${ leapYear ? 'es' : 'no es' } Bisiesto`;
  res.send(message);
});

app.listen(config.port, () => {
  console.log(`Server on http://localhost:${config.port}`);
});

function isLeapYear(year) {
  return year % 4 == 0 && year % 100 !== 0 || year % 400 === 0;
}

*nota: No s贸lo es suficiente con dividir entre 4 tambi茅n hay que evaluar si no es divisible entre 100 o si es divisible entre 400,

Mi soluci贸n

Mi c贸digo, simple y efectivo.

const express = require("express");

const app = express();
const { config } = require("./config/index");

app.get("/", (req, res) => {


if(req.query.year % 100 ===0 && req.query.year % 4 ===0 ){
    console.log("Es bisiesto");
}else if(req.query.year % 100 !==0 && req.query.year % 4 ===0){
    console.log("Es bisiesto");
}else{
    console.log("No es bisiesto");
}
    res.send();

});


app.listen(config.port, () => {
  console.log(`listen on http://localhost:${config.port}`);
});```


Este es el mio 馃榾

app.get('/bisiesto?', function (req, res) {
  const { fecha } = req.query;
  let message, status;
  const aux = new Date(fecha);
  if (isNaN(aux.getFullYear())) {
    status = 400;
    message = 'Usa el query para pasar una fecha valida';
  } else {
    status = 200;
    message = aux.getFullYear() % 4 === 0 ? 'es bisiesto' : 'no es bisiesto';
  }
  res.status(status).send({ message });
});

Anexo respuesta al challenger

const express = require('express');

const app = express();

const { config } = require('./config/index');


function bisiesto(ano) {
  if (((ano % 4 === 0) && (ano % 100 !== 0))  || (ano % 400 === 0)){
    return 'es bisiesto.';
  } else {
    return 'no es bisiesto.';
  }
}

app.get('/:ano', function (req, res) {
  res.set('Content-Type', 'text/plain');
  let texto=`El a帽o ${req.params.ano} ${bisiesto(req.params.ano)}`;
  res.end(texto);
});

app.listen(config.port, function () {
  console.log(`Listening en http://localhost:${config.port}/2020`)
});

src/utils/index.js

const isLeapYear = (year) => {
  return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
};

module.exports = {
  isLeapYear,
};

route -> index.js

app.get('/leapyear/:year', (req, res) => {
  const year = req.params.year;
  res.send(`El a帽o ${year} ${isLeapYear(year) ? 'es' : 'no es'} bisiesto`);
});

Mi c贸digo con una funci贸n ternaria para validar que ingresen un n煤mero v谩lido

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

const { config } = require('./config/index');

app.get('/', function (req, res) {
  res.send('Hello World');
});

app.get('/json', function (req, res) {
  res.json({ hello: 'World' });
});

app.get('/:year', function (req, res) {
  const year = req.params.year;

  const leapYear = () => {
    if ((year % 4 == 0 && year % 100 !== 0) || year % 400 == 0) {
      return res.send(`El a帽o ${year} es bisiesto`);
    } else {
      return res.send(`El a帽o ${year} no es bisiesto`);
    }
  };

  function validateYear(){
      isNaN(year) == true ? res.send('Debes ingresar un a帽o'): leapYear();
    };

  validateYear();
});

app.listen(config.port, function () {
  console.log(`Listening http://localhost:${config.port}`);
});```