Link Maps, acorta tu URL y descubre nuevos lugares

Link Maps, acorta tu URL y descubre nuevos lugares

Link Maps es una aplicación web fullstack que actúa como acortador de URLs y generador de códigos QR. Cada enlace acortado se asocia con una posición aleatoria en el mundo, permitiendo a los usuarios descubrir nuevos lugares.

  1. NodeJS
  2. JavaScript
  3. Express
  4. PostgreSQL
  5. Sequelize
  6. React
  7. Zustand
  8. Bootstrap
  9. MapLibre

Link Maps es un acortador de URL y generador de códigos QR, a cada uno de los enlaces acortados se asigna una posición aleatoria a lo largo del mundo para descubrir nuevos lugares.

Se trata de una aplicación web fullstack, en cuánto fue necesario construir una aplicación que funcionara en el lado del servidor para gestionar las peticiones HTTP que realizan los usuarios solicitando acortar una URL y obtener el enlace original; asi como una aplicación del lado del cliente para que el usuario disponga de una interfaz visual para acortar su enlace, obtener el código QR, observar la ubicación asociada a su enlace acortado, asi como abrir en enlace acortado para redirigirlo a la URL original.

El desarrollo de este sistema se dividió en dos partes: desarrollo frontend y desarrollo backend. A continuación se procederá a dar los detalles de cada uno.

Desarrollo backend

Se inicio por el backend, donde se levanto un servicio web con express. Se utilizó la arquitectura MVC manejando solamente dos tipos de peticiones HTTP, inspirado en el tipo API-REST:

  • GET (leer un enlace): Se envía el conjunto de caracteres que representan el enlace acortado como un query param para obtener como respuesta el enlace acortado, el enlace original, la latitud, la longitud y en enlace de la posición en Google Maps.
  • POST (crear un enlace): Se envía en el body de la petición el enlace original. para obtener como respuesta el conjunto de caracteres que representa el enlace original acortado, la latitud y longitud del punto aleatorio y su enlace de Google Maps.

Para leer un enlace se tienen algunos elementos en cuenta:

  1. Mediante Zod, se valida que el query param cumpla las condiciones de un enlace corto, estas son: letras mayúsculas, minúsculas y dígitos. Adicionalmente, no puede superar el número de caracteres permitido, este se define mediante una variable de entorno para ser cambiada en cuyo caso se requiera.

De la misma manera, para crear un enlace se debe tener en cuenta:

  1. Mediante Zod, se valida que efectivamente el enlace original corresponda a un enlace. Se permiten los protocolos HTTP y HTTPS, el enlace debe incluir un TLD y no puede contener los siguientes caracteres [<>”\’`] los cuales no son comunes en una URL.
  2. Si el enlace es correcto, con la función randomPoint() de Turf se crea un punto aleatorio el cual se verifica que exista una intersección entre este y el vector de continentes que dispone Natural Earth, el cual fue convertido a formato GeoJSON. Para verificar esta intersección se emplea la función booleanIntersects() , en cuyo caso el punto aleatorio no se encuentre dentro del GeoJSON de continentes, se genera otro punto aleatorio hasta que se cumpla la condición. El punto generado se trata de un archivo GeoJSON y se extraen la latitud y longitud de su única feature.
  3. La función randomString() se encarga de generar el conjunto de caracteres aleatorio; de manera similar al punto aleatorio, se verifica que la cadena aleatorio no se encuentre en la base de datos, en cuyo caso se encuentre, se crea uno nuevo hasta que sea un elemento único.
  4. El modelo de datos de la base de datos es muy simple, el cual es una única tabla con los siguientes atributos:
    1. id: Identificador único.
    2. shortLink: Conjunto de caracteres que representan el enlace original acortado.
    3. longLink: Enlace original.
    4. lat: Latitud del punto aleatorio asociado.
    5. lng: Longitud del punto aleatorio asociado.
    6. createdAt: Fecha y hora en la cual se creó el enlace.

Por último, se emplearon algunos middlewares como cors y express-rate-limit para limitar las peticiones desde una misma IP a la API pública para evitar sobrecargar el servidor.

Para hacer la API agnóstica al motor de bases de datos se empleó Sequelize, mientras que el cliente y los datos de conexión se manejan como variables de entorno. El motor de bases de datos seleccionado fue PostgreSQL, empleando el servicio gratuito en Aiven. Por otro lado, el despliegue de la API se realizó mediante un Web Service gratuito en Render.

Desarrollo frontend

Los requerimientos que debe cumplir la aplicación del lado del usuario son los siguientes:

  • En una página el usuario podrá ingresar su enlace original en el formulario para obtener el enlace acortado, descargar el código QR como imagen y observar la posición aleatoria que corresponde a su URL.
  • En la segunda página, la cual se obtiene al visitar la URL acortada, el usuario tendrá acceso a su enlace original y volver a consultar la posición asignada.

Como tecnologías se utilizó React como framework de JavaScript y Bootstrap como framework de CSS. Para la lectura dinámica de las páginas se empleó el paquete React Router, por otro lado, se decidió implementar multiples idiomas con i18next y react-i18next; en este momento, la aplicación se encuentra disponible en los idiomas principales como Inglés, Español, Francés, entre otros.

Para el mapa web o geovisor se utilizó la librería MapLibre, empleando las teselas gratuitas que dispone ESRI. Se emplea una estrategia en la cual la clase que define al mapa web se almacena como un estado global para tener este disponible en todos los elementos de la aplicación; de esta manera, se puede controlar el estado del mapa y realizar sobre este diferentes interacciones como agregar datos geográficos, rotarlo, cambiar de posición, etc.

La generación de los códigos QR y su descarga como imagen se realiza mediante las librerías react-qr-code y html-to-image. Para el estado global de la aplicación se utilizó Zustand, creando un único estado para agregar algunas variables y métodos.

A grandes rasgos, la aplicación se encarga de validar y leer el formulario diligenciado por el usuario. Cuando su único campo, es decir, el enlace original se encuentra correcto, hará una petición a la API, la cual le retornará el enlace acortado, la posición aleatoria y el enlace a Google Maps. Debido a que el servidor donde se hospede la aplicación puede variar, el DNS se almacena como una variable de configuración de la aplicación, este es el motivo por el cual en la base no se almacena la URL acortada completa, esta ruta la construye la aplicación.

Por otro lado, cuando el usuario ingresa a la dirección del enlace acortado, con React Router se obtiene se obtiene el recurso que se esta solicitando, es decir, la cadena de caracteres que representa la URL acortada. Con esta, se realiza una petición a la API para obtener el enlace original, además de la posición y el enlace a Google Maps.

Hasta la fecha de la presente publicación, la aplicación del lado del cliente aún no ha sido publicada pues se requiere mejorar el SEO de la página para que esta se muestre en los motores de búsqueda y se esta pensando en la posibilidad de explorar la incorporación de anuncios mediante Google Adsense.