- 1. Preámbulo
- 2. Resumen del proyecto
- 3. Objetivos de aprendizaje
- 4. Consideraciones generales
- 5. Criterios de aceptación mínimos del proyecto
- 6. Pistas, tips y lecturas complementarias
- 7 HTTP API Checklist
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 web (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) usando el protocolo HTTP (o HTTPS).
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 súper 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, PostgreSQL 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.
El objetivo principal de aprendizaje es adquirir experiencia con Node.js como herramienta para desarrollar aplicaciones de servidor, junto con una serie de herramientas comunes usadas en este tipo de contexto (Express como framework, MongoDB, PostgreSQL o MySQL como base datos, contenedores de docker, etc).
En este proyecto tendrás que construir un servidor web que debe servir JSON
sobre HTTP
, y desplegarlo en un servidor en la nube.
Para completar el proyecto tendrás que familiarizarte con conceptos como
rutas (routes), URLs, HTTP y REST (verbs, request, response,
headers, body, status codes...), JSON, JWT (JSON Web Tokens),
conexión con una base datos (MongoDB
, PostgreSQL
, o MySQL
),
variables de entorno, deployment, contenedores de docker
...
Reflexiona y luego marca los objetivos que has llegado a entender y aplicar en tu proyecto. Piensa en eso al decidir tu estrategia de trabajo.
-
Instalar y usar módulos con npm
-
Configuración de package.json
-
Configuración de npm-scripts
-
Pruebas unitarias (unit tests)
-
Pruebas asíncronas
-
Uso de mocks y espías
-
Pruebas de integración (end-to-end)
-
Módulos de ECMAScript (ES Modules)
-
Módulos de CommonJS
-
Uso de linter (ESLINT)
-
Uso de identificadores descriptivos (Nomenclatura y Semántica)
-
Git: Instalación y configuración
-
Git: Control de versiones con git (init, clone, add, commit, status, push, pull, remote)
-
Git: Integración de cambios entre ramas (branch, checkout, fetch, merge, reset, rebase, tag)
-
GitHub: Creación de cuenta y repos, configuración de llaves SSH
-
GitHub: Despliegue con GitHub Pages
-
GitHub: Colaboración en Github (branches | forks | pull requests | code review | tags)
-
GitHub: Organización en Github (projects | issues | labels | milestones | releases)
-
Manejo de rutas
-
Uso y creación de middleware
-
Consulta o petición (request) y respuesta (response).
-
Cabeceras (headers)
-
Cuerpo (body)
-
Verbos HTTP
-
Codigos de status de HTTP
-
Encodings y JSON
-
CORS (Cross-Origin Resource Sharing)
-
JWT (JSON Web Token)
-
Almacenamiento y acceso de contraseñas
-
Variables de entorno
-
Contenedores (Docker)
-
Docker compose
-
Instalación
-
Conexión
-
Queries y comandos (creación, lectura, actualización, eliminación)
Este proyecto se realizará en duos y deberá integrarse con el proyecto Burger Queen API client que desarrolle simultáneamente el equipo de Frontend developers de tu squad.
La lógica del proyecto debe estar implementada completamente en JavaScript.
En este proyecto está permitido usar librerías o frameworks, asi como
extensiones al lenguaje con babel
(caso en el cual deberás incluir un
comando npm run build
).
Los tests deben cubrir un mínimo del 90% de statements, functions, lines y branches. Si bien el boilerplate no incluye la configuración para pruebas unitarias, estas son obligatorias.
Otro requerimiento del equipo de QA de nuestra clienta es realizar pruebas end-to-end, que usaremos 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.
El boilerplate ya contiene el setup y configuración
necesaria para ejecutar todos los tests end-to-end con el comando npm run test:e2e
.
# Corre pruebas e2e sobre instancia local. Esto levanta la aplicación con npm
# start y corre los tests contra la URL de esta instancia (por defecto
# http://127.0.0.1:8080).
npm run test:e2e
# Corre pruebas e2e sobre URL remota
REMOTE_URL=<TODO: poner URL> npm run test:e2e
Las pruebas end-to-end ya están completas en el boilerplate, así que puedes usarlas como guía de implementación y checklist de completitud.
Según lo establecido por la documentación entregada por nuestra clienta, la API debe exponer los siguientes endpoints:
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
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 8888
Nuestra 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 entornoPORT
para 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.
Para este proyecto te recomendamos usar docker-compose
localmente (en tu
computadora) para ejecutar la aplicación junto con la base de datos
seleccionada. Por otro lado, con respecto al despliegue, no es obligatorio usar
docker-compose
, puedes elegir el proveedor (o proveedores) que prefieras junto
con el mecanismo de despligue y estrategia de alojamiento. Te recomendamos
explorar las siguientes opciones:
- Heroku es probablemente la opción más sencilla (la que requiere menos configuración) y nos permite alojar tanto el servidor web como la base de datos (PostgreSQL) en el mismo sitio con pocos clicks.
- Si quieres explorar opciones más personalizadas y ver docker del lado del servidor puedes cosiderar proveedores como AWS (Amazon Web Services) o GCP (Google Cloud Platform), ambos tienen algún tipo de free tier así como tanto instancias de servidores virtuales (VPS) donde configurar nuestro propio Docker o servicios para desplegar aplicaciones en contenedores (por ejemplo Compute Engine de GCP o Elastic Container Service de AWS).
- Si quieres trabajar con MongoDB, MongoDB Atlas es una muy buena opción para alojar nuestra base datos de producción, la cuál podemos usar en conjunción con cualquiera de las opciones mencionadas arriba.
Si tienes dudas sobre las diferentes (y múltiples) opciones de despliegue no dudes en consultar con tus pares y tus coaches.
ℹ️ Antes de comenzar a programar te recomendamos leer y seguir con detenimiento la guía de primeros pasos para ayudarte a elegir tu stack (base de datos, módulo para conectar a la base de datos desde Node.js, etc) y configurar tu entorno de desarrollo.
- Express
- MongoDB
- PostgreSQL
- MySQL
- docker
- docker compose
- ¿Qué es Docker? | Curso de Docker | Platzi Cursos
- Postman
- Variable de entorno - Wikipedia
process.env
- Node.js docs
-
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