💻
dws
  • Presentación
  • Introducción
  • Docker en DAW
  • PHP
  • MVC
  • Laravel
    • Laravel 6.*
    • Laravel 8.*
    • Laravel 9.*
    • Trabajo
    • API con Laravel
  • Node.js
    • Instalacion
    • Introduccion
    • Proyecto Hola Usuario
    • Servidor Express
    • Api REST
  • WEB SERVICES
    • Qué son?
    • REST
    • OAuth
  • Un paso más allá
    • OAuth con Google
    • reCAPTCHA
    • Google Calendar
    • API Aemet
Powered by GitBook
On this page
  • Descripción
  • Objetivos
  • Empezamos proyecto
  • Documentación
  • express
  • Ejecución
  • Prueba funcionamiento
  • Método listen
  • Añadir otra ruta
  • Código ruta contactar
  • Uso de JSON
  • Comprobar JSON
  • Middleware
  • Ejemplo de middleware
  • Logs a fichero
  • Solución logs a fichero
  • Más sobre logs
  • Uso de contenido estático
  • Configuración express para contenido estático
  • Template engine
  • Configuración de hbs
  • Uso de hbs
  • Partials mediante handlebars
  • Ejercicio templates
  • Uso de helpers
  • ¿Continuamos?

Was this helpful?

  1. Node.js

Servidor Express

PreviousProyecto Hola UsuarioNextApi REST

Last updated 5 years ago

Was this helpful?

Descripción

  • Montar un servidor web mediante paquetes propios de node

Objetivos

  • Entender la arquitectura de Express

    • Middleware

    • Uso de paquetes para extender la funcionalidad de Express

  • Creación de un servidor web que sirva:

    • Contenido estático

    • Contenido dinámico en base a templates

    • Content-type en JSON (para API posterior)

Empezamos proyecto

Documentación

    • Extensa pero concisa

    • Numerosos ejemplos

express

  • Instalar express mediante uno de los comandos siguientes:

    npm install --save express@4.16.3
    npm i -S express@4.16.3
  • Creamos el fichero server.js con el siguiente código:

const express = require('express')
const app = express()
app.get('/', (req, res) => {
    res.send('Hola Mundo')
})
app.listen(3000)

Ejecución

  • Debería ejecutarse de cualquiera de las siguientes maneras:

npm start
node server.js
  • Utiliza nodemon para evitar reinicios al cambiar código

Prueba funcionamiento

  • Se echa de menos algún tipo de mensaje de arranque

    • Cuando el método listen haya terminado...

Método listen

  • Permite añadir más parámetros

  • Un parámetro de tipo función (función de callback)

    • Es el único parámetro de este tipo, así los diferencia

app.listen([port[, host[, backlog]]][, callback])
app.listen(3000, () => {
  console.log('Servidor web arrancado en el puerto 3000')
})

Añadir otra ruta

  • Utiliza el plugin ExpressSnippet de Visual Code para completado

    • Comprueba su funcionamiento con el app.listen

  • Datos nueva ruta:

    • URL: /contactar

    • Muestre el mensaje Página para contactar

Código ruta contactar

app.get('/contactar', (req, res) => {
    res.send('Página para contactar')
})

Uso de JSON

  • Vamos a devolver un JSON en vez de un string:

app.get('/contactar', (req, res) => {
    res.send({
      nombre: 'pepito'
      email: 'pepito@gmail.com'
    })
})

Comprobar JSON

  • Utiliza algún plugin de formateo de JSON dentro del navegador

    • El JSON puede ser más complejo que el anterior, por ej:

      https://api.arasaac.org/api/pictograms/es/search/casa
  • Comprueba como cambia el content type

    • Utiliza las herramientas de desarrollo

    • El cambio lo hace directamente Express

  • Los datos en JSON podrían estar:

    • En una variable

    • Incluso en otro fichero

    • Recibirse vía API

    • ....

const contacto = require('./contacto.json')
app.get('/contactar', (req, res) => {
  res.send(contacto)
})

Middleware

  • Son funciones que:

    • Se registran por express mediante app.use y se ejecutan en orden

    • Tienen acceso al objeto de solicitud (req), al objeto de respuesta (res) y a la siguiente función de middleware (next)

app.use((req, res, next)=>{
  //operaciones del middleware
  next() //para ir al siguiente middleware o a la ruta
  // también podríamos hacer un send() y cortar
  // la cola de middlewares, por ej en un control de permisos
})

Ejemplo de middleware

  • Podemos crear un middleware que guarde traza de las fechas de accesos

  • Es importante el orden

    • Entre los middlewares

    • Antes que las peticiones get, post....

var app = express()

app.use(function (req, res, next) {
  var now = new Date().toString()
  console.log(`Time: ${now} ${req.method} ${req.url}`)
  next()
})

Logs a fichero

  • Completa el middleware anterior para que guarde los cambios en el fichero server.log

  • Piensa donde se debe poner el next() y si debes utilizar un método síncrono o asíncrono

Solución logs a fichero

app.use((req, res, next) => {
  var now = new Date().toString()
  var log = `${now}: ${req.method} ${req.url}`
  console.log(log)
  fs.appendFile('server.log', `${log}\n`, (err) => {
    if (err) console.log(`No se ha podido usar el fichero de log:  ${err}`)
  })
  next()
})

Más sobre logs

  • Podemos querer utilizar distintos transports o medios para logs

    • Ficheros

    • Consola

  • Distintos niveles (debug, err, warning...)

  • Distintos formatos de visualización (colores, negrita...)

  • Con posibilidad de ejecución de queries

  • ....

Uso de contenido estático

  • Crea un fichero .html en la carpeta public

    • Ayúdate de emmet: ! + tab

  • Express ya tiene un middleware integrado para contenido estático

    • No deja de ser una función como las vistas anteriormente

    • No necesitamos importarla mediante un require

    • Una vez importado, hace un send() si existe el fichero, si no, un next()

Configuración express para contenido estático

const staticRoute = path.join(__dirname, 'public')
app.use(express.static(staticRoute))
  • __dirname es la raíz del proyecto

  • path.join para que sea multiplataforma

  • Podríamos configurar un directorio virtual (static para public)

const staticRoute = path.join(__dirname, 'public')
app.use('/static', express.static(staticRoute))

Template engine

  • Mostrar un index.html está bien pero puede que necesitemos:

    • Inyectar valores en el html

    • "includes" para footer, header... (patrón diseño DRY)

  • Tenemos que elegir un motor de plantillas

Configuración de hbs

  • Instalación

    npm i -S hbs
  • Configuración

    // const hbs = require('hbs')
    app.set('view engine', 'hbs'); // clave valor
    • No hacemos un require porque no usamos ninguna función

    • express lo llama internamente

  • Indicamos a nodemon los tipos de ficheros a monitorizar (por defecto solo js):

"scripts": {
  "start": "nodemon server.js -e js,hbs"
},

Uso de hbs

  • Definimos una carpeta views donde irán las templates

  • Fichero views/contactar.hbs:

  ...
  <body>
    <h1>{{pageTitle}}</h1>
    <p>Aquí iría el formulario de contacto</p>

    <footer>
      <p>Copyright {{currentYear}}</p>
    </footer>
  </body>
  ....
  • Ejecutamos el método res.render() en vez de res.send()

    • Admite un objeto como segundo parámetro para pasar variables

app.get('/contactar', (req, res) => {
  res.render('contactar.hbs', {
    pageTitle: 'Contactar',
    currentYear: new Date().getFullYear()
  })
})

Partials mediante handlebars

  • Registramos el directorio donde se van a guardar:

const hbs = require('hbs')
hbs.registerPartials(path.join(__dirname, 'views', 'partials'))
app.set('view engine', 'hbs') // clave valor
  • Creamos fichero views/partials/footer.hbs:

  <footer>
    <p>Copyright {{getCurrentYear}}</p>
  </footer>
  • Lo incluimos dentro de nuestro fichero views/contactar.hbs:

  ...
  <body>
    <h1>{{pageTitle}}</h1>
    <p>Aquí iría el formulario de contacto</p>
    {{> footer}}
    <!-- con la linea anterior
       tendríamos el footer mediante partials -->

  </body>
  ....

Ejercicio templates

  • Añade una página de inicio además de contactar

  • Ambas deben cargar su correspondiente template que además cargará un partial para el header y otro para el footer

Uso de helpers

  • Se registran funciones que devuelven un código dinámico

  • Se pueden inyectar en cualquier template o partial.

hbs.registerHelper('getCurrentYear', () => new Date().getFullYear())
// con paso de parámetro:
hbs.registerHelper('toUpperCase', text => text.toUpperCase())
  • Podríamos eliminar el paso de currentYear a las vistas y utilizar el helper:

<footer>
  <p>Copyright {{getCurrentYear}}</p>
  <p>{{toUpperCase "Licencia MIT"}}</p>
 {{>header}}
</footer>

¿Continuamos?

  • Ya estamos preparados para utilizar express para crear una API

como añadir esa opción

Para ver las propiedades que nos hacen falta podemos usar la

Lo mejor es

Utilizaremos hbs que es un wrapper de

https://expressjs.com/
Mira en la documentación
API de Express
usar algún paquete que ya exista
hbs, ejs, pug (jade)...
handlebars
Creación de una API