Open source de un URL Shortener (versión Rust) completado tras 10 iteraciones de mejora
(github.com/lee-lou2)Después de crear, mejorar, volver a crear y volver a mejorar el proyecto de URL Shortener una y otra vez..., por fin terminé el proyecto open source v9, el final-final-final.
🚀 Github : https://github.com/lee-lou2/rust-url-shortener
Mientras preparaba el proyecto, me esforcé por cumplir sí o sí con los siguientes requisitos:
Requisitos
- La Short URL debe generarse muy rápido
- No debe volverse lenta aunque aumente la cantidad de datos
- Debe ser rápida sin importar cuándo, en qué situación o con qué datos se haga la solicitud
- También debe ser rápido redirigir la Short URL hacia la Original URL
- En realidad, esto es algo bastante obvio... 😅
- Debe incluir funciones adicionales que puedan satisfacer a distintos tipos de usuarios
- Si se desea, debe poder redirigir a una URL distinta según la plataforma
- Si se desea, el usuario debe poder revisar los datos que ingresan a la URL que generó
Para cumplir con estos requisitos, lo desarrollé de la siguiente manera:
Cambios aplicados
Q. ¿Cómo generar un Short Key de forma rápida sin depender de la cantidad de datos?
A.
En general, existen varias formas de generar un Short Key.
La primera es generar un valor aleatorio, verificar en la base de datos si ya existe y, si no existe, usarlo tal cual. Pero en este caso está la molestia de tener que consultar la base de datos y volver a generar el valor otra vez. Además, cuando ya hay muchos datos o llega el momento de cambiar la longitud del Short Key, pueden producirse demoras importantes.
La segunda es generar Short Keys aleatorios por adelantado y luego asignarlos. Como solo hay que hacer el match con Short Keys ya preparados, se puede generar siempre una Short URL rápidamente. Sin embargo, esto tampoco es la respuesta definitiva. Puede haber un límite en lo que se puede preparar de antemano, y si en algún momento se generan más Short URLs de las que ya estaban preparadas, aparecen consideraciones adicionales que resolver.
Entonces, ¿no habría una forma todavía mejor?
Después de pensarlo mucho, apliqué el siguiente método: combinar una cadena aleatoria de 4 caracteres con una cadena generada a partir del PK. La explicación de cada valor está abajo. El orden es el siguiente. Cuando el usuario solicita la creación de una Short URL, se genera una cadena aleatoria de 4 caracteres y se guarda tal cual en la base de datos. Al guardarla, el PK emitido se convierte en una cadena según el método explicado abajo. Luego se combina la cadena aleatoria generada al inicio con la cadena del PK para crear el Short Key. De esta forma, por más que se acumulen muchísimos datos, se puede generar de manera rápida, segura y sin duplicados.
- ¿Cadena aleatoria de 4 caracteres?
Aquí, la cadena aleatoria de 4 caracteres es una cadena realmente aleatoria compuesta por letras minúsculas, mayúsculas y números. No pasa nada si esta cadena llega a duplicarse. - ¿PK como cadena?
Luego está el segundo valor: la cadena del PK. Supongamos que creamos cadenas en orden combinando letras minúsculas, mayúsculas y números. El orden sería letras minúsculas de a -> z, letras mayúsculas de A -> Z y números de 0 -> 9. Entoncesasería el primer valor creado,bel segundo,cel tercero, y así sucesivamente, combinando valores de forma secuencial. Cuando se termine hasta9, se puede seguir aumentando la longitud conaa,ab,ac, etc. Si se construye así en orden, cada cadena termina teniendo un índice correspondiente. El índice deasería 1, por ejemplo. Y ahí está la clave: el PK se convierte en el índice, y solo hay que encontrar la cadena correspondiente a ese PK.
Q. ¿Cómo hacer que la redirección de la Short URL a la Original URL sea rápida?
A.
Aquí fui con algo muy simple: usar caché. Hay muchos servicios posibles, pero en este proyecto apliqué caché en memoria para poder consultar los datos rápidamente. Además, las funciones adicionales aparte de simplemente consultar los datos y redirigir, se procesan creando hilos ligeros.
Q. ¿Qué funciones adicionales implementaste?
A.
Primero, implementé redirección a distintas URL según la plataforma. Se reciben y guardan los DeepLink base de iOS y Android, y en caso de que no se pueda abrir el DeepLink, también se recibe un FallbackUrl. Además, se recibe la URL a la que se debe redirigir cuando se accede desde desktop, cubriendo así todos los casos.
Segundo, agregué una función para que el usuario pueda revisar los logs de acceso en el momento en que se redirige a la Original URL, recibiendo una URL de webhook y llamándola cada vez que se redirige a la Original URL. Por ahora, está implementado para enviar solo el User Agent y la información de la Short URL.
Tercero, al crear una Short URL permití ingresar adicionalmente la información de las etiquetas Head. El objetivo de esto es personalizar las etiquetas og. Si no se ingresan esas etiquetas, el sistema guarda la información de head de la Default URL.
Este proyecto fue hecho con Rust. La verdad es que apenas llevo 2 meses aprendiendo Rust. Al principio desarrollé el proyecto de URL Shortener con FastAPI, y después también lo desarrollé con Golang. Luego, mientras aprendía Rust, me atrapó muchísimo su atractivo y volví a crear una vez más un proyecto de URL Shortener completamente mejorado.
Todavía no me resultan del todo familiares la sintaxis, ownership y lifetimes, así que puede haber partes del código que se queden cortas. Les agradecería mucho su interés, apoyo y feedback 🙏
Gracias por leer hasta el final
17 comentarios
También publiqué otros proyectos, les agradecería mucho su interés 🎉
https://es.news.hada.io/topic?id=18647
Es un proyecto excelente.
¡Como mencionaste, sería genial que tuviera soporte para Docker!
Gracias 👏 Agregaré Docker durante esta semana y lo subiré 🙇♂️
¿El correo electrónico es obligatorio? No sabía que si no se verifica el correo no se pueden usar los webhooks ni generar direcciones.
Si quizá lo usarán solo de forma interna y necesitan personalización, puedo hacerles una versión personalizada por separado, aparte de ese proyecto.
Sí, como estaba pensado para usarse como un servicio público, lo configuré para que el correo electrónico sea obligatorio (usando verificación por correo sin registro de usuario).
También voy a pensar una forma de modificarlo para que no haga falta correo electrónico al ingresar el JWT 🙏
Vaya, estoy instalando Ubuntu en Lightsail y siguiendo los pasos, pero hay bastantes cosas que instalar, como SSL,
pkg-config, sqlite y cargo :) Yo pensaba usar Cloudflare Tunnel para la parte dehttpsen vez de NPM, pero igual siento que esto me queda difícil jaja.. ¡Estaré esperando la versión con Docker! Justo estaba dándole vueltas a qué hacer ahora que desaparecieron los dynamic links, así que esto me viene de maravilla.Agregué el Dockerfile y un comando ejecutable (
deploy.sh) 🎉Agregaré Docker lo antes posible jajaja
Oh, pero sí logré ejecutarlo. ¿Cómo lo hice? sorprendido
Creo que estaría bueno agregar una URL de demo también en el sitio web, además del README del repo de GitHub.
Normalmente primero reviso la información de la derecha del repositorio para ver si hay una página oficial o un playground, así que pensé que no había un sitio de demo jaja.
¡Muy buen proyecto, lo disfruté mucho!
¡Uy, se me había pasado! Voy a configurarlo ahora mismo, gracias 🤩
¡Se nota el cuidado puesto en este proyecto!
Yo también hice y uso algo parecido en la empresa, y en mi caso tuve que configurarle el conjunto de caracteres para evitar caracteres ambiguos, porque tenía que salir impreso en medios físicos.
También había contenido relacionado en GeekNews.
https://es.news.hada.io/topic?id=14479
¡Está bueno! Al generar el id o el enlace, sí ayuda bastante que tomen eso en cuenta.
Guau, gracias 👍
¡Puedes usarlo de inmediato con solo instalar Rust y configurar las variables de entorno!
El servicio de URL de Google se cierra este año, así que úsalo como alternativa. Cualquier duda, parte que necesite mejoras, método de instalación y otros temas; todos los correos son bienvenidos 👏
Puedes probarlo fácilmente en https://f-it.kr/ 🙇♂️