Introducción a NodeJs

nodejs
javascript
servidor
Introducción a NodeJs cover image

Introducción

Al tratar de aprender sobre la web

desarrollo, generalmente encontramos que el front-end es significativamente más accesible que el back-end. Hay muchas razones para esto, particularmente la sensación de retroalimentación instantánea que proviene de cambiar un cierto elemento de una página en el código y notar el cambio que se aplica al sitio web. Esta retroalimentación suele ser útil para los principiantes, ya que les permite ajustar su código y aprender de sus errores. Desafortunadamente, no es el caso con el backend: a menudo, una cantidad significativa de trabajo se dedica a configurar el entorno por adelantado e instalar las dependencias necesarias para que aparezca un mensaje simple de "Hola mundo" en el terminal. Afortunadamente, se está progresando constantemente en la comunidad de código abierto para facilitar el proceso de desarrollo de marcos y mejorar la experiencia del desarrollador. NodeJs es un buen ejemplo de esto. Este marco es una tecnología muy capaz que hace que escribir código del lado del servidor en Javascript sea conveniente, y ofrece una variedad de herramientas y características integradas que lo diferencian de sus competidores. En este artículo, exploraremos NodeJs y su ecosistema, con un enfoque práctico, construyendo un proyecto completamente funcional.

¿Qué construiremos?

Las aplicaciones ToDo son un proyecto de acceso para principiantes que aprenden desarrollo front-end. Es por eso que decidimos crear una API de lista de tareas pendientes. Esto nos permitirá agregar persistencia de datos a nuestra interfaz y nos dará la capacidad de manipular estos datos (agregando, actualizando, eliminando todos, etc.).

El código final se puede encontrar aquí.

Nuestras herramientas

Usaremos una pila de tecnología simplificada para este proyecto. Se puede considerar como una versión mínima de muchas herramientas que encontrará en proyectos de la vida real, ya que las ideas de nivel superior son las mismas. Los detalles de implementación y elección de una herramienta específica sobre otra no son importantes para comenzar.

  • NodeJs, como mencionamos, es uno de los marcos de Javascript más populares para crear aplicaciones del lado del servidor.

  • ExpressJs es un marco Javascript mínimo que se usa sobre NodeJS. Acelera el proceso de desarrollo mediante el uso de muchas funciones integradas. También se utiliza como una forma de estandarizar las prácticas de desarrollo en los proyectos de NodeJS para facilitar su uso a los ingenieros.

  • LowDB es una base de datos en memoria simple. Su simplicidad nos permite mostrar cómo interactuar con una base de datos en un proyecto de NodeJs, sin tratar temas más avanzados como implementaciones y configuraciones.

Ahora que identificamos todas las herramientas que usaremos, ¡vamos a nuestros teclados y comencemos a codificar!

Instalación

Node está disponible en todas las plataformas. Todas las guías de instalación se pueden encontrar en el sitio web oficial. Los usuarios de Windows deben asegurarse de agregar el nodo ruta a las variables de entorno para que pueda usarse en la línea de comandos.

También necesitaremos npm instalado. Npm es el administrador de paquetes estándar para NodeJs. Nos permitirá gestionar las dependencias de nuestro proyecto. La guía de instalación se puede encontrar aquí.

Inicialización del proyecto

Dirígete al enlace y clona el proyecto inicial:

Este es un repositorio de inicio simple para nuestro proyecto. Contiene todas las dependencias que usaremos junto con la estructura de archivos del proyecto. Explicaremos cada elemento una vez alcanzado. Abra su terminal, navegue hasta la ruta del proyecto y ejecute el comando:

npm install

Esto instalará todas las dependencias del proyecto especificado en el archivo package.json. package.json es el archivo que se encuentra en la raíz de cualquier proyecto Javascript/NodeJs, contiene metadatos sobre este último y se usa para administrar todas las dependencias, scripts y versiones del proyecto.

Después de instalar todas las dependencias, podemos iniciar nuestra aplicación:

npm run start

“start” es un script que especificamos en el paquete. archivo json. Especifica el archivo de entrada a nuestra aplicación, que en nuestro caso es app.js.

Ahora debería aparecer el siguiente mensaje en su terminal:

nodejs_1

Esto significa que nuestro servidor se inició correctamente y está escuchando cualquier solicitud enviada al puerto 3000. Veamos app.js y expliquemos qué está sucediendo aquí:

nodejs_2

App.js es nuestro archivo de entrada de proyecto (y el único en este momento). Instanciamos una aplicación expresa llamada app, especificamos que todas las solicitudes que tienen el método http "GET" y la subruta '/' serán manejadas por esta ruta, pasan una función llamada middleware, que toma el objeto de solicitud y respuesta como parámetros. Esto es crucial, ya que la solicitud contiene toda la información necesaria para su manejo (parámetros, cuerpo de la solicitud, encabezados de la solicitud, etc.), y el objeto de respuesta es el que se devolverá al cliente. Comenzamos simplemente enviando el mensaje "Hola mundo". Después de eso, hacemos que nuestra aplicación escuche cualquier solicitud entrante en el puerto especificado (en nuestro caso, 3000) y registramos el mensaje "Escuchando el puerto 3000" para indicar que nuestra aplicación está funcionando y lista para recibir solicitudes.

Abre tu terminal y en la barra de enlaces escribe “localhost:3000/”, y presiona Enter. Esta es la ruta especificada que podemos usar para llegar a nuestro servidor localmente. Recibirá el siguiente mensaje:

nodejs_3

Configuración de la base de datos

Lowdb es una base de datos de código abierto que es fácil de usar y no requiere una configuración específica. La idea general detrás de esto es almacenar todos los datos en un archivo json local. Después de instalar LowDB (que se hizo cuando instalamos todas las dependencias), podemos agregar el siguiente código a db.js:

nodejs_4

Este código es bastante similar al que se encuentra en la documentación oficial de LowDB. Lo modificamos un poco para nuestro propio caso de uso. Vamos a explicarlo línea por línea:

Las primeras líneas son para importar las dependencias necesarias. "unirse" es una función de utilidad disponible en el módulo "ruta". Es uno de los módulos centrales de NodeJs que ofrece una gran cantidad de métodos para tratar y manejar rutas. "Low" y "JSONFile'' son las dos clases expuestas por LowDB. El primero crea la instancia del archivo json que contendrá nuestros datos. El segundo crea la instancia de la base de datos real que actuará sobre ella. Finalmente, "lodash" es una de las bibliotecas de JavaScript más utilizadas que ofrece una amplia variedad de funciones de utilidad para tareas de programación comunes. Lo agregamos a nuestra instancia de base de datos para permitirnos usar sus métodos avanzados para manejar nuestros datos.

Primero, especificamos la ruta para el archivo db.json. Es el archivo que contendrá nuestros datos y se pasará a LowDB. Si el archivo no se encuentra en la ruta especificada, LowDB creará uno.

Luego pasamos la ruta del archivo al adaptador LowDB y la pasamos a nuestra nueva instancia de base de datos LowDB. La variable "db" se puede usar para comunicarse con nuestra base de datos. Una vez que se crea la instancia de la base de datos, leemos el archivo json usando db.read(). Esto establecerá el campo "datos" en nuestra instancia de base de datos para que podamos acceder al contenido de la base de datos. Tenga en cuenta que antecedimos esta línea con "await". Esto es para especificar que esta instrucción puede tardar un tiempo desconocido en resolverse y que el proceso de NodeJs debe esperar su ejecución antes de continuar con el resto del código. Hacemos esto porque la operación de lectura requiere acceso a la memoria del archivo especificado, y el tiempo para ejecutar este tipo de operación depende de las especificaciones de su máquina.

Ahora que tenemos acceso al campo de datos, lo configuramos como un objeto que contiene una matriz vacía de publicaciones, o más bien, verificamos si el archivo contiene datos anteriores y configuramos la matriz vacía si no es el caso.

Finalmente, ejecutamos db.write() para aplicar las modificaciones que hicimos a los datos y exportamos la instancia de la base de datos para que pueda usarse en otros archivos de nuestro proyecto.

Flujo de trabajo de solicitud/respuesta general

Considere el siguiente diagrama:

nodejs_5

Muestra la arquitectura general aplicada en una gran cantidad de aplicaciones de back-end creadas con NodeJs/Express. Comprender el flujo de trabajo general detrás del manejo de una solicitud no solo le permitirá crear y estructurar aplicaciones de NodeJs, sino que también le permitirá transferir estos conceptos a prácticamente cualquier pila técnica de su elección. Exploraremos las diferentes capas que interfieren con este proceso y explicaremos sus funciones:

## Capa de solicitud HTTP

Esta es la primera capa de nuestra aplicación, imagínela como una puerta de enlace que recibe una amplia gama de solicitudes diferentes provenientes de diferentes clientes, luego cada solicitud se analiza y se reenvía a la parte dedicada de la aplicación para que se maneje.

  • Enrutadores: aquí nos referimos a los enrutadores Express, pero este concepto se puede encontrar en muchos marcos de backend. Los enrutadores son una forma de aplicar la distribución lógica en nuestra lógica comercial a nuestro código, lo que significa que cada conjunto de elementos que comparten características similares son manejados por la misma entrada y pueden separarse del resto de los conjuntos. Esto tiene la ventaja de hacer que cada componente del código sea independiente de los demás y más fácil de mantener y ampliar. Más concretamente, ya modo de ejemplo, todas las solicitudes que cumplan las condiciones de la ruta de la url compartida “/posts” serán gestionadas por el mismo router. Dependiendo de su método http (GET, POST, etc.), se utilizará un controlador diferente.

  • Controladores: un controlador recibe solicitudes filtradas de los enrutadores, aplica procesamiento adicional y llama a los métodos de servicio adecuados.

Capa de lógica de negocios

Esta capa es única según los casos de uso específicos de la aplicación y la lógica comercial detrás de ella.

  • Servicios: Los servicios son un conjunto de métodos que contienen la lógica central de la aplicación. También interactúan con la base de datos mediante el uso de ORM/ODM.).

  • Servicios de terceros: muchas aplicaciones modernas optan por delegar una parte de la lógica de la aplicación a servicios dedicados accesibles a través de una API. Los servicios de este tipo pueden ser servicios de manejo de pagos, almacenamiento de archivos estáticos, notificaciones y otros.

  • ODM/ORM: Los ORM y ODM actúan como intermediarios entre los servicios y la base de datos. Su función es proporcionar una abstracción de alto nivel sobre una base de datos que permite a un desarrollador escribir código en el lenguaje de programación de su elección en lugar de lenguajes de base de datos dedicados, como SQL.

## Capa de persistencia de datos

  • Bases de datos: como mencionamos anteriormente, casi todas las aplicaciones necesitan algún tipo de persistencia de datos. Esta parte la manejan las bases de datos y, dependiendo de la naturaleza de los datos, la lógica comercial y muchas otras consideraciones, la elección de una determinada base de datos sobre otra se considera crucial para la eficiencia y la escalabilidad de la aplicación.

## Ejemplo: agregar una publicación

Ahora que entendemos la idea general detrás de la arquitectura, apliquémosla a nuestro ejemplo simple. Implementaremos la función de agregar una publicación de tareas pendientes a nuestra aplicación. Supongamos que cualquier publicación tiene una identificación única que nos permitirá identificarla más tarde en nuestra base de datos, un título que es una cadena y un orden que es de tipo entero. Siguiendo nuestro diagrama, comenzaremos implementando el enrutador. Agregue el siguiente código al archivo index.js:

Iniciando un servidor en ExpressJS

Este es nuestro archivo de enrutador. Importamos express y el método "addPost" desde nuestro controlador (implementaremos este en breve), creamos una instancia de enrutador express y vinculamos el método addPost a nuestro enrutador, lo que significa que para cada solicitud que tenga la ruta raíz y el método http "POST", se llamará al método "addPost" para manejarlo.

Antes de implementar nuestro método en el controlador, hacemos referencia al nuevo enrutador en nuestro archivo app.js principal y especificamos su ruta como "/posts": todas las rutas con las rutas especificadas se reenviarán a este enrutador, por lo que puede ser manejado por los diferentes métodos del controlador:

Iniciando un servidor en ExpressJS

Importamos el router y lo nombramos como “posts”. app.use(“/posts”,..) significa que todas las solicitudes con la subruta “/posts”, sin importar su método http, se enrutarán al enrutador especificado.

Otros cambios en app.js incluyen la importación del archivo de configuración de la base de datos para que se ejecute y el uso de express.json() como un middleware que nos permite acceder al objeto del cuerpo de la solicitud.

Ahora que nuestras rutas están configuradas, podemos agregar el método "addPost" en el archivo controller.js:

Iniciando un servidor en ExpressJS

“addPost” es una función de middleware que toma como parámetros la solicitud, los objetos de respuesta y la siguiente función. Cuando se llama a la siguiente función, el proceso pasará al siguiente middleware de la cadena o finalizará la solicitud. En el código del método, extraemos el título y el orden del cuerpo de la solicitud y los pasamos como parámetros a la función de servicio "createPost". Esta función toma los atributos de la publicación, crea una nueva publicación y la devuelve. Una vez que se crea la nueva publicación, se la devolvemos al cliente junto con el código de estado 200, lo que significa que la solicitud se ha realizado correctamente. Puede notar que nuestro código se coloca dentro de un bloque try/catch para detectar cualquier error inesperado y pasarlo al siguiente middleware. Se considera una buena práctica adjuntar a todos los enrutadores un middleware de manejo de errores que extraiga el error y devuelva un mensaje de error significativo al cliente.

Todo lo que queda ahora es implementar la función "createPost" en service.js:

nodejs_6

Como mencionamos anteriormente al explicar las diferentes capas de la arquitectura, la capa de servicio interactúa con la solución de almacenamiento de datos mediante el uso de ORM/ODM. Sin embargo, en nuestro ejemplo, no necesitaremos usar un ORM separado, ya que Lowdb viene con soporte integrado para Javascript. Todos los detalles sobre su sintaxis se pueden encontrar en la documentación.

El método "createPost" recibe el título y el orden como parámetros, y los usa para crear el objeto de la publicación. Para la identificación única, usamos una biblioteca dedicada llamada "nanoid", que genera una secuencia única de caracteres. Agregamos la nueva publicación en la matriz de publicaciones en la base de datos y escribimos estos cambios; la función devuelve la nueva publicación.

Ahora que "createPost" está listo, la función de agregar publicaciones ya está terminada y en funcionamiento. Lo probamos usando Postman, una herramienta popular para probar API:

nodejs_7

Seleccionamos "POST" como el método http para la solicitud junto con la ruta de URL especificada "localhost: 3000/posts". Agregamos el título y el orden como formato json en la sección del cuerpo y enviamos la solicitud. Como se muestra arriba, recibimos el estado 200 OK junto con la publicación recién creada.

Conclusión

En este proyecto se exploraron muchos conceptos e ideas: cubrimos cómo instalar y configurar nuestro entorno de proyecto, aprendimos cómo configurar LowDB para la persistencia de datos locales, exploramos la arquitectura general de las aplicaciones de back-end de NodeJS/Express y vimos cómo aplicarlo en un ejemplo simple. Finalmente, probamos nuestra aplicación usando Postman.

La intención aquí era exponer una versión simplificada de todo lo que implica la creación de aplicaciones de back-end modernas. Como vimos anteriormente, NodeJs es una herramienta poderosa que nos permite crear API simples y complejas. Combinado con su rico ecosistema de marcos, como express y una gran cantidad de herramientas y bibliotecas para casi cualquier caso de uso, es una solución legítima para el desarrollo de back-end moderno, una solución que recomendamos aprender y dominar.


Career Services background pattern

Servicios profesionales

Contact Section background image

Mantengámonos en contacto

Code Labs Academy © 2024 Todos los derechos reservados.