El sitio se encuentra desplegado en dos sitios, el cliente está en Vercel y el servidor y la base de datos fueron desplegados con Railway.
Cliente: https://treehouse-andressiri.vercel.app
Servidor: https://treehouse-andressiri.up.railway.app
Se trata de una aplicación para el manejo de los datos de una escuela ficticia llamada "Treehouse". Los requerimientos son poder realizar las operaciones básicas de los diversas entidades presentes en esta lógica y poder manejar las distintas relaciones entre ellas. En otras palabras, para los salones, estudiantes y profesores se requiere poder crear información que los represente, poder modificar esta información, eliminarla si fuera necesario y poder acceder a ella cuando se lo solicita. A su vez, respecto a las relaciones, se debe poder saber quienes forman parte de un determinado salon y agregarlos o quitarlos del mismo. Por otro lado esta escuela considera información de importancia saber relaciones de hermanos entre sus estudiantes, por lo cual es necesario poder registrar dicha información.
Estas son algunas de las acciones que se pueden realizar:
- Crear y editar las distintas entidades a través de formularios:
- Eliminar las distintas entidades (salones, estudiantes y profesores):
- Ver los distintos alumnos de un salón y elegir quitarlos o verlos en detalle:
- Definir a un estudiante como hermano de otro/s estudiante/s:
- Agregar estudiantes o profesores a un salon:
- Agregar imágenes para reconocerlos mejor:
Next.js
Next.js es un framework de React para construir aplicaciones web del lado del servidor. Proporciona características como renderizado del lado del servidor (SSR), pre-renderizado estático, enrutamiento simple y escalabilidad. Además, Next.js viene con algunas características incorporadas para mejorar el rendimiento, como la división de código y la precarga automática de páginas. También es compatible con una amplia variedad de bibliotecas y herramientas de desarrollo, lo que lo convierte en una herramienta poderosa para desarrolladores de todos los niveles de experiencia. En resumen, Next.js es una excelente opción para aquellos que desean desarrollar aplicaciones web rápidas y escalables utilizando React.
TypeScript
TypeScript es un lenguaje de programación de código abierto desarrollado y mantenido por Microsoft. Es una superconjunto tipado de JavaScript que agrega características como tipos de datos estáticos opcionales, interfaces, clases y decoradores. Estas características permiten una mayor verificación de errores y una mejor documentación del código, lo que lo hace más fácil de mantener y escalar. TypeScript se compila a JavaScript para su uso en navegadores web y en entornos de servidor. Es una herramienta popular para el desarrollo de aplicaciones de una sola página (SPA), aplicaciones de Node.js, y para proyectos de código abierto y empresariales.
Node JS
Node.js es un entorno de ejecución orientado a eventos asíncronos para JavaScript construido con V8, motor de JavaScript de Chrome, y diseñado para crear aplicaciones network escalables. Por supuesto Node.js tiene varios pros y contras comparado con otros lenguajes y frameworks con los que compite, pero las principales razones que explican por qué lo elegí para este proyecto son, primero, por la ventaja de poder utilizar "Javascript en todos lados", siendo que Node.js soporta Javascript tanto en el lado del cliente como en el lado del servidor, y segundo, el vasto repositorio de librerías al que se tiene acceso con Node Package Manager.
Express
Express es una infraestructura web rápida, minimalista y flexible para Node.js que proporciona un conjunto sólido de prestaciones. La principal razón por la cual la elegí es que, sin agregar muchas restricciones, hace mucho más claro y fácil el control de las peticiones y las respuestas y el diseño de rutas con, como dice en su sitio oficial, "con miles de métodos de programa de utilidad HTTP y middleware a su disposición".
React JS
React es una librería de Javascript de código abierto eficiente, declarativa, y flexible para construir interfaces de usuario simples, rápidas, y escalables para el frontend de aplicaciones web. Utiliza JSX que es una extensión de sintaxis de JavaScript que permite mezclar HTML, lo que facilita el desarrollo de componentes. Elegí React en su momento por recomendaciones, siendo que estoy de acuerdo con las razones que me dieron: que es más fácil de aprender y usar en un principio y que tiene un enorme potencial cuando se lo aprende en profundidad, que tiene un gran apoyo de la comunidad y que es empleado ampliamente en el mercado laboral IT; junto con otras ventajas tecnológicas como un renderizado rápido. Hoy en día, utilizando Next.js no tengo dudas de que tomñe ua buena decisión.
PostgreSQL
PostgreSQL es un poderoso sistema de bases de datos objeto-relacional. Una de las razones para tomar esta decisión en lugar de elegir otra base de datos relacional es que es de código abierto con más de 30 años de actividad y hay una gran cantidad de información fácil de encontrar que describe cómo instalarla y utilizarla en la documentación oficial. Otra razón importante es que algunas funciones, como crear, actualizar o eliminar, en mi opinión, tienen un mejor retorno de información luego de que la acción es realizada.
Sequelize
Sequelize es un moderno Mapeador de Objetos Relacionales u ORM (por las siglas en inglés de Object Relational Mapping) para TypeScript y Node.js en conjunto con PostgresSQL y otras bases de datos relacionales SQL. Siendo un ORM, Sequelize me permite acceder a la base de datos usando una lógica orientada a objetos con Javascript, una gran ventaja. La utilización del cliente de sequelize con las migraciones y los seeders realmente facilita la creación, el trabajo y las pruebas con la base de datos.
Json Web Token
JSON Web Token (JWT) es un estándar abierto (RFC 7519) que define una forma compacta y contenida en sí misma de transmitir de forma segura información entre dos partes en formato de objeto JSON. Esta información puede ser verificada y es confiable porque está cifrada digitalmente, ya que los tokens pueden ser cifrados utilizando un secreto o un par de llaves público/privado. Elegí esto para mis métodos de autorización y autenticación porque resulta en una manera bastante sencilla de llevarlos a cabo. Me parece mejor que otras opciones, como Passport, esto debido a que encuentro menos restricciones, pese a que Passport provea un middleware ya incluído que tuve que desarrollar en este caso.
Material UI
Material UI es un proyecto de código abierto que cuenta con componentes de React que implementan Material Design de Google. Con la experiencia que tengo trabajando con distintos frameworks de CSS, la opción que más me atrae es MUI5 con Emotion o Styled Components. Permite la utilización de componentes de mayor orden y una mejor modularización y separación de intereses.
Utilicé esta tecnología que está en boga, y no por nada, para obtener toda la información necesaria para rellenar la página con un contenido mínimo.
La API se encuentra documentada con Postman en este sitio. Tiene ejemplos de lo que solicita cada petición y de lo que se puede esperar como respuesta. También se puede cargar en Postman para probarlo en local con el siguiente botón:
El proyecto cumple con lo requerido y algunas de las funcionalidades extra. Por cuestiones de tiempo algunas cosas no se terminaron de desarrollar en el cliente. Un ejemplo de esto es la autenticación y autorización de usuarios, que está desarrollada (y temporalmente desactivada) en el servidor pero no en el cliente. A su vez se vieron modificadas algunas expectativas de cómo hacer distintas visualizaciones en relación al rol de usuario, o la posibilidad de crear grupos que no sean visibles al público en general si fuera necesario. Asimismo, los estilos podrían mejorarse y algo que sí es necesario de hacer es la responsividad para dispositivos móviles. En las últimas ramas de trabajo, por los mismos motivos nombrados, que el tiempo apremiaba, algunos archivos se pueden ver un poco más desprolijos que otros, o encontrarse alguna desprolijidad en la repetición de código, nada de lo que no sea conciente, pero dejando el perfeccionismo a un lado hay debía poder adaptarme a la situación. De todas formas, el código escrito, sobretodo el referente al servidor que no sufrió de estas complicaciones, es muestra de un buen trabajo y la capacidad de resolver, lo solicitado y lo que pueda acontecer.
Para instalar esta aplicación y probarla en desarrollo necesitas tener instaladas en tu computadora versiones actualizadas de Node.js
, NPM
y Git
para poder:
-
Crear e ir a un nuevo directorio.
-
Inicializar un nuevo repositorio con el comando
git init
. -
Obtener este repositorio remoto con el comando
git pull https://github.com/andressiri/Treehouse
. -
Instalar las dependencias del directorio raíz con el comando
npm install
. -
Ir al directorio
/client
e instalar las dependencias con el comandonpm install
nuevamente. -
Ir al directorio
/server
e instalar las dependencias con el comandonpm install
una vez más. -
Crear un bucket con el servicio S3 de AWS.
-
Crear la base de datos PostgreSQL requerida:
Instalar el servidor PostgreSQL en tu computadora.
- Descargar el instalador en el sitio oficial.
- En Windows considerar que es necesario haber ingresado como administrador o superusuario para realizar la instalación. De ser necesario, se recomienda seguir las instrucciones para Windows provistas en el sitio oficial.
- En Mac OS considerar que hay que correr el paquete dmg descargado como usuario administrador. De ser necesario, se recomienda seguir las instrucciones para Mac OS provistas en el sitio oficial.
- En Ubuntu para Linux seguir las instrucciones provistas en el sitio oficial para Ubuntu.
- Necesitarás la constraseña que ingreses en la instalación para conectarte a la base de datos.
-
Crear un archivo
.env
en el directorio/server
con las siguientes variables:NODE_ENV = development PORT = 8080 JWT_SECRET = < una cadena que quieras usar como secreto para el token de JWT > MAILER_MAIL = < tu dirección de email de gmail > MAIL_APP_PASSWORD" = < tu "contraseña de aplicación" generada desde google (no es la constraseña de tu email) > AWS_ACCESS_KEY = < tu llave de acceso AWS > AWS_SECRET_ACCESS_KEY = < tu llave de accesso secreta de AWS > AWS_BUCKET_NAME = < el nombre del bucket del servicio S3 de AWS > ALLOW_CORS = http://localhost:300 (o el puerto en el que corras el cliente) DB_USER = < "postgres" (default) o tu nombre de usuario para la base de datos de PostgreSQL > DB_PASSWORD = < la contraseña para ese usuario de PostgreSQL > DB_NAME = < el nombre que elijas para tu base de datos PostgreSQL > DB_HOST = localhost DB_PORT = 5432
Cómo generar una contraseña de aplicación en Google
Para generar una nueva contraseña de aplicación seguir los siguientes pasos:
-
En una nueva pestaña de Chrome ir a "Gestionar tu cuenta de Google".
-
Ir a "Iniciar sesión en Google" en la sección de "Seguridad" y clickear en "Contraseñas de aplicaciones". Notar que es necesario tener la verificación en dos pasos activada para poder hacer esto.
-
Crear una nueva constraseña de aplicación, el nombre es indistinto.
-
Obtener la nueva contraseña de aplicación creada.
-
-
Crear un archivo
.env.local
en el directorio/client
con las siguientes variables:
NEXT_PUBLIC_API_ORIGIN = http://localhost:8080 (o el puerto en el que elijas correr el servidor)
- Crear la base de datos, hacer las migraciones y poblarla con el comando
npm run createdb
en el directorio server. Esto correrá tres comandos del cliente de Sequelize. El primero creará la base de datos, el segundo creará las tablas necesarias con las condiciones necesarias para el funcionamiento de la API y el tercero poblará la base de datos. Para el correcto funcionamiento es necesario mantener actualizadas las carpetas de migraciones, modelos y seeds de la carpeta/server/db/sequelizeCLI
con las carpetas correspondientes creadas al hacer el build deTypescript
, ya que el client de sequelize (sequelize-cli) sólo corre en "runtime". Carpetas iniciales son provistas, pero debe considerarse al hacer cambios. - Finalmente, para correr el cliente en el puerto 3000 usar el comando
npm run dev
en el directorio/client
, y para el servidor en el puerto 8080 usar el comandonpm run dev
en el directorio/server
.