29 points par leelou2 2025-01-06 | 17 commentaires | Partager sur WhatsApp

À force de créer un projet d’URL Shortener, de l’améliorer, puis d’en recréer un, puis de l’améliorer encore… j’ai enfin abouti au projet open source v9, la vraie vraie version finale.

🚀 Github : https://github.com/lee-lou2/rust-url-shortener


En préparant ce projet, j’ai vraiment essayé de respecter les exigences suivantes.

Exigences

  1. Les Short URL doivent être générées très rapidement
  • Elles ne doivent pas ralentir à mesure que le volume de données augmente
  • Elles doivent rester rapides quelles que soient les circonstances, le moment ou les données utilisées dans la requête
  1. La redirection d’une Short URL vers l’Original URL doit elle aussi être rapide
  • En réalité, c’est assez évident… 😅
  1. Le service doit inclure des fonctionnalités additionnelles capables de satisfaire différents types d’utilisateurs
  • Si nécessaire, il doit être possible de rediriger vers des URL différentes selon la plateforme
  • Si nécessaire, l’utilisateur doit pouvoir consulter les données d’entrée générées par l’URL qu’il a créée

Pour répondre à ces exigences, j’ai développé le projet de la manière suivante.

Éléments mis en œuvre

Q. Comment générer un Short Key rapidement, indépendamment du volume de données ?
A.
De manière générale, il existe plusieurs façons de générer un Short Key.
Premièrement, on peut générer une valeur aléatoire, vérifier si elle existe déjà dans la base de données, et si ce n’est pas le cas, l’utiliser telle quelle. Mais cette méthode implique la contrainte de devoir vérifier la base puis éventuellement regénérer une valeur. En outre, lorsqu’il y a déjà beaucoup de données, ou au moment où la longueur du Short Key doit changer, cela peut provoquer d’importants délais.
Deuxièmement, on peut générer à l’avance des Short Key aléatoires, puis les associer au moment voulu. Comme il suffit alors d’effectuer un matching avec des Short Key déjà préparés, on peut toujours créer les Short URL rapidement. Mais cela non plus n’est pas une solution parfaite. Il peut y avoir des limites à ce qu’on peut pré-générer, et il faut aussi gérer des cas supplémentaires, par exemple lorsque davantage de Short URL sont créées que prévu.
Alors, n’y a-t-il pas une meilleure méthode ?
Après de nombreuses réflexions, j’ai appliqué l’approche suivante : combiner une chaîne aléatoire de 4 caractères avec une chaîne dérivée de la PK. Voici le principe. Lorsqu’un utilisateur demande la création d’une Short URL, une chaîne aléatoire de 4 caractères est générée puis enregistrée telle quelle dans la base de données. La PK émise lors de l’enregistrement est ensuite convertie en chaîne selon la méthode décrite ci-dessous. Enfin, la chaîne aléatoire initiale et la chaîne issue de la PK sont combinées pour former le Short Key. Ainsi, quelle que soit la quantité de données accumulées, la génération reste rapide, sûre et sans doublons.

  • Un nombre aléatoire de 4 caractères ?
    Ici, cette valeur aléatoire de 4 caractères est en réalité une chaîne vraiment aléatoire composée de lettres minuscules, de lettres majuscules et de chiffres. Il n’est pas grave si cette chaîne est dupliquée.
  • Convertir la PK en chaîne ?
    Passons maintenant à la deuxième valeur, la chaîne issue de la PK. Imaginons que l’on crée des chaînes en combinant dans l’ordre les lettres minuscules, les lettres majuscules et les chiffres. L’ordre serait le suivant : lettres minuscules de a à z, lettres majuscules de A à Z, puis chiffres de 0 à 9. Dans ce cas, a serait la première valeur créée, b la deuxième, c la troisième, etc., et l’on pourrait ainsi composer des valeurs successives. Une fois arrivé à 9, on continuerait avec aa, ab, ac, en augmentant aussi le nombre de caractères. En procédant ainsi séquentiellement, chaque chaîne obtient un index correspondant. L’index de a serait donc 1. C’est là que la méthode intervient : la PK devient l’index, et il suffit de retrouver la chaîne correspondant à cette PK.

Q. Comment accélérer la redirection d’une Short URL vers l’Original URL ?
A.
Ici, j’ai utilisé tout simplement un cache. Il existe différents services, mais dans ce projet j’ai appliqué un cache en mémoire afin de pouvoir récupérer rapidement les données. En complément, les fonctionnalités additionnelles qui vont au-delà de la simple récupération des données et de la redirection sont traitées via des threads légers.

Q. Quelles fonctionnalités additionnelles avez-vous implémentées ?
A.
Premièrement, j’ai mis en place une redirection vers des URL différentes selon la plateforme. Les DeepLink par défaut pour iOS et Android sont enregistrés séparément, et j’ai également ajouté une FallbackUrl à utiliser lorsqu’il est impossible d’ouvrir le DeepLink. J’ai aussi prévu l’URL de destination pour les accès depuis desktop afin de couvrir tous les cas.
Deuxièmement, pour que l’utilisateur puisse consulter les journaux de connexion au moment où l’on redirige vers l’Original URL, j’ai ajouté une fonctionnalité qui accepte une URL de webhook et l’appelle à chaque redirection vers l’Original URL. Pour l’instant, seules les informations de User Agent et de Short URL sont transmises.
Troisièmement, lors de la création d’une Short URL, il est possible de saisir en plus les informations de la balise Head. L’objectif est de permettre la personnalisation des balises og. Si ces balises ne sont pas renseignées, les informations head de la Default URL sont enregistrées par défaut.


Ce projet a été réalisé avec Rust. En réalité, cela fait seulement 2 mois que j’apprends Rust. Au départ, j’avais développé un projet d’URL Shortener avec FastAPI, puis je l’avais aussi développé en Golang. Ensuite, en découvrant Rust, j’ai été tellement séduit que j’ai voulu recréer une nouvelle fois un projet d’URL Shortener entièrement amélioré.

Comme je ne suis pas encore totalement à l’aise avec la syntaxe, l’ownership ou encore les lifetimes, il peut y avoir des points faibles dans le code. Je serais donc très reconnaissant pour votre intérêt, votre soutien et vos retours 🙏

Merci d’avoir lu jusqu’au bout

17 commentaires

 
leelou2 2025-01-09

J’ai aussi publié d’autres projets, merci de leur accorder beaucoup d’intérêt 🎉
https://fr.news.hada.io/topic?id=18647

 
po5678 2025-01-07

C’est vraiment un excellent projet.
Comme vous l’avez écrit, ce serait vraiment formidable si Docker était pris en charge !

 
leelou2 2025-01-07

Merci 👏 J’ajouterai Docker dans le courant de la semaine et je le mettrai en ligne 🙇‍♂️

 
po5678 2025-01-07

L’adresse e-mail est-elle obligatoire ? Je ne savais pas que sans vérification de l’e-mail, il était impossible de créer un webhook ou une adresse.

 
leelou2 2025-01-07

Si vous souhaitez l’utiliser uniquement en interne et qu’une personnalisation est nécessaire, je peux aussi vous proposer une version sur mesure séparément de ce projet !

 
leelou2 2025-01-07

Oui, pour l’utiliser comme service public, j’ai fait en sorte que l’e-mail soit obligatoire (avec une vérification par e-mail sans inscription).

Je vais aussi réfléchir à une solution pour que l’e-mail ne soit pas nécessaire lors de la saisie du JWT 🙏

 
po5678 2025-01-07

Waouh, j’installe Ubuntu sur Lightsail et j’essaie de suivre, mais il y a vraiment beaucoup de choses à installer, comme le SSL, pkg-config, sqlite, cargo, etc. :) Pour la partie https, je comptais utiliser Cloudflare Tunnel plutôt que NPM, mais décidément ça reste trop difficile pour moi haha.. J’attendrai avec impatience une version Docker ! Justement, comme les dynamic links ont disparu, je me demandais quoi faire, donc c’est vraiment une super nouvelle.

 
leelou2 2025-01-07

J’ai ajouté le Dockerfile et la commande exécutable (deploy.sh) 🎉

 
leelou2 2025-01-07

J’ajouterai Docker dès que possible mdr

 
po5678 2025-01-07

Oh mais je l’ai quand même exécuté ! Comment j’ai fait déjà ? Héhé

 
jin225675 2025-01-07

Je pense que ce serait bien d’ajouter une URL de démo sur le site web du dépôt GitHub, en plus du readme !

En général, je regarde d’abord les informations à droite du dépôt pour vérifier s’il y a une page d’accueil ou un playground, donc j’ai cru qu’il n’y avait pas de site de démo haha.

J’ai pris beaucoup de plaisir à découvrir ce super projet !

 
leelou2 2025-01-07

Ah, je l’avais raté, je vais le configurer tout de suite. Merci 🤩

 
balthasar 2025-01-07

On voit qu’il y a du soin dans ce projet !
Moi aussi, j’ai créé et j’utilise quelque chose de similaire dans mon entreprise ; dans mon cas, comme cela devait apparaître sur des supports imprimés, j’ai défini le jeu de caractères de manière à éviter les caractères ambigus.

Il y avait aussi un sujet lié sur GeekNews.

https://fr.news.hada.io/topic?id=14479

 
laeyoung 2025-01-07

C’est pas mal !! Quand on génère un id ou un lien, c’est vrai que c’est mieux de prendre ça en compte.

 
leelou2 2025-01-07

Waouh, merci 👍

 
leelou2 2025-01-06

Il suffit d’installer Rust et de définir les variables d’environnement pour pouvoir l’utiliser immédiatement !
Le service d’URL de Google prend fin cette année, utilisez-le comme alternative. Toutes les questions ou remarques sont les bienvenues par e-mail, qu’il s’agisse de points à améliorer, de la méthode d’installation ou de tout autre sujet 👏

 
leelou2 2025-01-06

Vous pouvez l’essayer facilement sur https://f-it.kr/ 🙇‍♂️