Un pequeño restaurante de hamburguesas, que está creciendo, necesita un sistema a través del cual puedan tomar pedidos usando una tablet, y enviarlos a la cocina para que se preparen ordenada y eficientemente.
Este proyecto tiene dos áreas: interfaz (cliente) y API (servidor). Nuestra clienta nos ha solicitado desarrollar la API que se debe integra con la interfaz, que otro equipo de desarrolladoras está trabajando simultáneamente
Con una API en este caso nos referimos a un servidor web, que es básicamente un programa que escucha en un puerto de red, a través del cual podemos enviarle consultas (request) y obtener respuestas (response).
Un servidor web debe manejar consultas entrantes y producir respuestas a esas consultas que serán enviadas de vuelta al cliente. Cuando hablamos de aplicaciones de servidor, esto implica una arquitectura de cliente/servidor, donde el cliente es un programa que hace consultas a través de una red (por ejemplo el navegador, cURL, ...), y el servidor es el programa que recibe estas consultas y las responde.
Node.js nos permite crear servidores web super eficientes de manera relativamente simple y todo esto usando JavaScript!
En este proyecto partimos de un boilerplate que ya contiene una serie de endpoints (puntos de conexión o URLs) y nos piden completar la aplicación. Esto implica que tendremos que partir por leer la implementación existente, y familiarizarnos con el stack elegido (Node.js y Express) y complementarlo con un motor de bases de datos, el cual tu deberás elegir entre MongoDB y MySQL.
La clienta nos ha dado un link a la documentación que especifica el comportamiento esperado de la API que expondremos por HTTP. Ahí puedes encontrar todos los detalles de qué endpoints debe implementar la aplicación, qué parámetros esperan, qué deben responder, etc.
- Express
- MongoDB
- docker
- docker compose
- Postman
- Variable de entorno - Wikipedia
process.env- Node.js docs- ssh
- Apollo-Server
Este proyecto fue realizado en duos y se integró con el proyecto Burger Queen API client que se desarrolló simultáneamente con el equipo de Frontend developers.
Se realizarón pruebas end-to-end, para verificar el comportamiento desde el punto de vista de HTTP, desde afuera del servidor. Estos tests, a diferencia de las pruebas unitarias, no prueban cada pieza por separado sino que prueban la aplicación completa, de principio a fin. Estas pruebas, al no hacer uso directo del código fuente de la aplicación, pueden ejecutarse directamente sobre una URL remota, ya que la interfaz sometida a pruebas es HTTP.
Según lo establecido por la documentación entregada por nuestra clienta, la API debe exponer los siguientes endpoints:
GET /
POST /auth
GET /usersGET /users/:uidPOST /usersPUT /users/:uidDELETE /users/:uid
GET /productsGET /products/:productidPOST /productsPUT /products/:productidDELETE /products/:productid
GET /ordersGET /orders/:orderidPOST /ordersPUT /orders/:orderidDELETE /orders/:orderid
La clienta nos ha solicitado que la aplicación cuente un comando npm start
que se debe encargar de ejecutar nuestra aplicación node y que además pueda
recibir información de configuración, como el puerto en el que escuchar, a qué
base datos conectarse, etc. Estos datos de configuración serán distintos entre
diferentes entornos (desarrollo, producción, ...). El boilerplate ya implementa
el código necesario para leer esta información de los
argumentos de invocación
y el
entorno.
Podemos especificar el puerto en el que debe arrancar la aplicación pasando un argumento a la hora de invocar nuestro programa:
# Arranca la aplicación el puerto 8888 usando npm
npm start 8888Nuestra aplicación usa las siguientes variables de entorno:
PORT: Si no se ha especificado un puerto como argumento de lína de comando, podemos usar la variable de entornoPORTpara especificar el puerto. Valor por defecto8080.DB_URL: El string de conexión de MongoDB o MySQL. Cuando ejecutemos la aplicación en nuestra computadora (en entorno de desarrollo), podemos usar el una base de datos local, pero en producción deberemos utilizar las instancias configuradas condocker-compose(mas sobre esto en la siguiente sección de Deployment)JWT_SECRET: Nuestra aplicación implementa autenticación usando JWT (JSON Web Tokens). Para poder firmar (cifrar) y verificar (descifrar) los tokens, nuestra aplicación necesita un secreto. En local puedes usar el valor por defecto (xxxxxxxx), pero es muy importante que uses un secreto de verdad en producción.ADMIN_EMAIL: Opcionalmente podemos especificar un email y password para el usuario admin (root). Si estos detalles están presentes la aplicación se asegurará que exista el usuario y que tenga permisos de administrador. Valor por defectoadmin@localhost.ADMIN_PASSWORD: Si hemos especificado unADMIN_EMAIL, debemos pasar también una contraseña para el usuario admin. Valor por defecto:changeme.
Nuestra clienta nos ha manifestado que su equipo de devops está siempre con muchas
tareas, por por lo que nos pide como requerimiento que la aplicación esté configurada
con docker-compose para que pueda ser desplegada sin dificultades en cualquier
entorno.
El boilerplate ya cuenta con una configuración incial de docker-compose para
la aplicación de node, tu tarea será extender esa configuración para incluir la
configuración de base de datos que hayas elegido.
Ten en cuenta que como vas a tener dos servidores corriendo sobre una misma
configuración, deberás exponer los servicios en diferentes puertos.
Una vez que tengas tu configuración de docker-compose, deberás crear un servidor
en la nube (VPS) (en el área de recursos te proponemos algunas alternativas de
proveedores), acceder a él a través de ssh, clonar tu repositorio y ejecutar
docker-compose up para levantar la aplicación y la documentación, para que
queden online y accesibles.
- Express
- MongoDB
- MySQL
- docker
- docker compose
- Postman
- Variable de entorno - Wikipedia
process.env- Node.js docs- TODO: providers de VPS recomendados, idealmente con un free tier o muy baratos.
- ssh
-
GET /
-
POST /auth
-
GET /users -
GET /users/:uid -
POST /users -
PUT /users/:uid -
DELETE /users/:uid
-
GET /products -
GET /products/:productid -
POST /products -
PUT /products/:productid -
DELETE /products/:productid
-
GET /orders -
GET /orders/:orderid -
POST /orders -
PUT /orders/:orderid -
DELETE /orders/:orderid

