nodemonrest

API RESTfull en NodeJS, MongoDB, JWT, AWS para fines didácticos

Usage no npm install needed!

<script type="module">
  import nodemonrest from 'https://cdn.skypack.dev/nodemonrest';
</script>

README

NodeMonREST

Ejemplo de API REST en NodeJS, usando Mongo, JWT y AWS S3 con CI/CD bajo GitHub Actions para fines docentes.

NodeMonRest CI/CD Docker Heroku Release Licence JS Code JS Style

Acerca de

Este proyecto tiene nombre de Pokemon :). El objetivo principal docente es aplicar distintas técnicas para construir un esqueleto de API REST usable en distintos proyectos. La idea es hacer un esqueleto lo suficientemente genérico, adaptable y extensible en módulos para ser aplicado en distintos problemas y con él resolver cuestiones que se nos pueden presentar genéricas en cada uno de ellos, con el objetivo de mostrar para el ámbito docente como poder realizarlo. Es una aplicación puramente docente. Entre las distintas técnicas usadas:

  • Distribución de los elementos del sistema. Tenemos distribuídos en distintos nodos cada uno de los componentes cruciales del sistema: codigo, información y almacenamiento de ficheros.
  • Patrón MVC. La vista será cualquier cliente que consuma nuestra API.
  • Asíncronía y respuesta a Eventos. Uso de promesas e interacción basada en eventos que es uno de los aspectos más fuetes de NodeJS.
  • Acceso a bases de datos NoSQL usando Mongo DB.
  • Autenticación y autorización usando JWT.
  • Autorización basada en permisos de usuario.
  • Manejo de CORS
  • Algunos patrones de diseño conocidos.
  • JS Código ECMA2019. De esta manera nos aseguramos seguir los estándares marcados para este tipo de lenguaje, pero tratando los módulos como indica NodeJS, usando Babel para compatibilidad. Además se ha aplicado el stilo AirBnB uno de los más seguidos con el objetivo de mantener una flosofía de sintáxis y estilo de programación ampliamente seguida en la comunidad JS/Node.
  • Almacenamiento en la nube usando AWS.
  • Desarrollo CI/CD usando GitHub Actions.

Iré comentando los aspectos más relevantes y las librerías usadas en cada parte.

Requisitos del sistema

Dependencias Versión
node >= 10.0.0
npm >= 6.4.0
yarn >= 1.22.0

Instalación y uso

Tareas que podemos ejecutar dentro de nuestra aplicación. Te recomiendo leer el fichero package.json:

  • npm install: para instalar las dependencias
  • npm run start-dev: ejecuta el entorno de desarrollo, el codigo en src
  • npm run watch: ejecuta nodemon para ver los cambios del código sobre la marcha
  • npm run build: construye la versión de distribución (en el directorio dist)
  • npm start (npm run start): ejecuta la versión de distribución, antes has tenido que ejecutar npm build
  • npm run test (o test-x) Ejecuta todos los test o el test x(auth, recipes, users) que quieras.

Usando Heroku

Heroku te permite crear tu propio contenedor dinámico y lanzar la apliación. Puedes acceder a él, tanto la web como la API en esta dirección: https://nodemonrest.herokuapp.com/

Usando NPM

Puedes usar NPM para instalar el proyecto: npm i nodemonrest

Usando Docker

También podemos usar Docker para su instalación como se indica y proceder como en apartado anterior. La imagen la tienes disponible en: https://hub.docker.com/r/joseluisgs/nodemonrest. Además puedes proceder:

  • Pull de la imagen: docker pull joseluisgs/nodemonrest
  • Ejecutando luego: docker run -p 49160:8000 -d joseluisgs/nodemonest (de esta manera exponemos los puertos en nuestra maquina es el 49160, que se mapea al 8000 del docker, puedes usar el puerto que quieras en vez del 4961)

El fichero .ENV

El servidor toma las constantes del fichero .env, te dejo un ejemplo de configuración en .env_example. Cámbialo y lo configuras a tu gusto y luego lo renombras. Es importante que conozcas las variables de entorno que necesitas, si algunas no las pones las cogerá por defecto de la clase env que se encarga de gestionarlas. Si no las tienes te dará un error.

Carpeta Mongo

En la carpeta mongo tienes un volcado de la base de datos y de cada una de las colecciones con datos de ejemplo. el resto de tablas se crea sobre la marcha. Te recomiendo usar Mongo Atlas y en ella crear la base de datos recipes, o como tu quieras que se llame, recuerda que debes cambiarlo en .env. Posteriormente crea las colecciones si quieres tener estos datos que se llamen igual, si no se irán creando sobre la marca vacías.

Usando Postman

Puedes usar Postman para testear la API. Puedes consultar en la web (dependiendo como entres si localmente o usando la dirección disponible) las opciones existentes o simplemente carga en este programa el fichero con las operaciones disponibles.

Tecnologías y librerías usadas: Un poquito de su desarrollo

  • NodeJS. JS en Servidor.
  • Mongo DB. He usado su versión en la nube Atlas
  • Express. Framework de aplicaciones web para la API. Con ellos creo y gestiono las rutas. Además nos permite fácilmente crear middlewares, con lo cual podremos aplicar logs específicos, filtrar para autorizaciones y autenticaciones y ampliar mediante middleware. Es lo que más me gusta de esta librería. Te recomiendo mirar el código de los ficheros route y middleware para ver como realizo estas acciones. Una de las cosas importantes es como he creado el servidor para que pueda ser levantado como instancia en cada una de las pruebas.
  • Mongoose. Conjunto de librerías para operar con bases de dato MongoDB. He implementado el acceso usando singletón.
  • JWT-Simple. Para implementar la atenticación basada en JWT. Esta librería actúa en base a middleware con Express. Los propios tokens que caducan dependiendo del valor de .env TOKEN_LIFE en minutos. Para la parte de autorización, también los hemos encapsulado en ellos los permisos de usuario que tengan. También hemos usado el refresco de tokens, en base a UUID almacenando los tokens de refresco en MongoDB con un índice TTL de la colección en base al valor de .env TOKEN_REFRESH en minutos. De esta manera se autodestruyen pasado ese tiempo y libera el tokens de refresco asociado al token de usuario, dando un poco de seguridad extra. El objetivo de implementar este tipo de token de refresco es que si el access token tiene fecha de expiración, una vez que caduca, el usuario tendría que autenticarse de nuevo para obtener un access token. Con el refresh token, este paso se puede saltar y con una petición al API obtener un nuevo access token que permita al usuario seguir accediendo a los recursos de la aplicación, hasta que el refresh token caduque. Se debe tener en cuenta que el TTL del Token de autentificación debe ser menor que el de refresco.
  • BCrypt. Librería de criptografía para manejar las contraseñas de los usuarios.
  • Body Parser. Middleware que parsea los body como objetos.
  • Cors. Middleware para manejo de CORS.
  • Dotenv. Para leer las variables de entorno del fichero .env
  • Morgan. Middleware Request logger el cual nos permitirá sacar logs de nuestras peticiones HTTP.
  • UUID. Implementa el RFC4122 UUIDs para los tokens de refresco.
  • Express-fileupload. Es un middleware para Express el cual nos ayuda a procesar peticiones multipart o subida de imágenes. Se ha puesto que el tamaño máximo por umagen sea 2MB aunque se puede cambiar el el fichero .env. Los directorios para almacenar imágenes o ficheros están en .env, puedes poner el mismo o lo que quieras, pues se crean dinámicamente dentro de public/uploads (FILES_PATH) y accesible directamente por la ruta url/files (FILES_URL). Puedes ponerle el mismo si quieres.
  • AWS Se ha implementado el sistema de almacenamiento en a nube para no depender localmente del servidor. Si quieres la versión en el servidor revisa esta rama. La idea de usar este tipo de tecnologías es aprender a usar almacenamiento en la nube siguiendo la folosofía de distribución de cada uno de los elementos del sistema: código, bases de datos y ficheros.
  • Joi. Nos sirve para validar los datos de entrada en base a un esquema de validación, por si no lo usamos en los propios esquemas de mongo la validación. Es importante que el back valide todos los datos por si se ha escapado algo del Front. No podemos dejar nada a la surte. ¡Luke, somos la última esperanza!
  • Mongoose-unique-validator. Nos sirve para validar los campos unique. Actúa como middleware.
  • Underscore. Nos permite extender las posibilidades de la programación funcional para algunos métodos.
  • Express-handlebars. Personalmente uno de los mejores motores de plantillas para NodeJS, basado en Handlebars. Lo he usado de ejemplo para hacer algunas páginas estáticas de presentación de la API.
  • Mocha y Chai. Se han utilizado estas librerías para los test por su funcionalidad y porque se adaptan perfectamente al proceso de integración continua que se ha marcado como objetivo.
  • Babel y ESLint con el objetivo de construir un código ampliamente compatible y estandarizado de JS.
  • GitHub Actions. Es una de las grandes herramientas que se ha usado para la integración/distribución continuas CI/CD. Para ello hemos integrado el entorno de ejecución con pruebas y el despliegue como docker en DockerHub y su despliegue para su uso en Heroku.

Autor

GitHub

Licencia

Este proyecto esta licenciado bajo licencia MIT, si desea saber más, visite el fichero LICENSE