Créer un raccourcisseur d'URL avec Bref - Partie 2
Dans la précédente partie, on a pu voir comment initialiser une application serverless avec Bref. On a également mis en place notre première fonction qui s’occupe de rediriger le visiteur vers l’adresse de destination.
Pour pouvoir enregistrer de nouveaux liens raccourcis, il faut modifier le fichier contenant la liste des liens et mettre en ligne la nouvelle version de notre fonction. Ce n’est pas le plus pratique dans un usage courant.
Dans cet article, on va voir comment permettre d’enregistrer de nouveaux liens en mettant en place une API d’enregistrement de nouveaux liens.
Permettre la modification de la liste des liens
L’objectif est de faire en sorte que l’on puisse enregistrer de nouveaux liens raccourcis de la manière la plus simple possible. Pour cela, on va faire évoluer notre raccourcisseur d’URL afin de lui ajouter une API d’enregistrement de liens raccourcis.
Cette API demande une ou plusieurs adresses à raccourcir et fournira en retour les URL raccourcis respectives. Comme cela, il sera possible d’enregistrer facilement des liens avec un client d’API, en créant une interface d’administration ou tout simplement avec un appel cURL.
Pour y parvenir, on va :
- créer un emplacement de stockage pour le fichier de lien en dehors de la fonction de redirection
- modifier la fonction de redirection des visiteurs afin de lire le fichier depuis le nouvel emplacement de stockage
- créer une base de données pour stocker les liens enregistrés
- créer une fonction pour l’API pour enregistrer le lien dans une base de données
- créer une fonction pour mettre à jour le fichier de liens lors de l’enregistrement d’un lien en base de données
Stocker la liste de liens en dehors de la fonction
Le fichier link.json
est pour l’instant embarqué avec le code source de la fonction. Pour le mettre à jour, il faut
déployer une nouvelle version de la fonction. On va modifier la fonction afin de lire le fichier depuis un emplacement
externe à la fonction Lambda.
On va utiliser le service Amazon S3 qui sert à stocker des fichiers. Il permet également de garder des anciennes versions de fichiers sans nécessiter un outil de gestion de versions comme git.
Dans un premier temps, on va déployer un bucket S3 pour l’utiliser comme emplacement de stockage. Grâce à Serverless framework et à Lift, on va pouvoir créer automatiquement ce bucket lors du déploiement de notre application. Il est possible de créer un bucket S3 en utilisant directement la configuration via CloudFormation mais cela est plus compliqué et verbeux.
On va d’abord installer le plugin Lift pour pouvoir l’utiliser dans notre application :
npm install -g serverless-lift
Ensuite, on va modifier notre configuration serverless.yml
afin d’activer le plugin et de déclarer un emplacement de
stockage.
serverless.yml
diff --git a/serverless.yml b/serverless.yml
--- a/serverless.yml
+++ b/serverless.yml
@@ -7,7 +7,8 @@
deploymentMethod: direct # fastest deployment method
plugins:
- - ./vendor/bref/bref
+ - serverless-lift
+ - ./vendor/bref/bref
functions:
redirect:
@@ -20,6 +21,10 @@
method: 'GET'
path: '/{id+}'
+constructs:
+ published-links:
+ type: storage
+
# Exclude files from deployment
package:
patterns:
Le bucket sera créé la prochaine fois qu’on lancera la commande serverless deploy
.
Maintenant que nous avons un bucket disponible, nous pouvons maintenant l’utiliser dans notre fonction afin de lire le fichier de liens. On supposera que le fichier a été déposé sur S3 et donc qu’il est forcément disponible.
On va avoir besoin d’accéder à notre bucket S3 depuis notre fonction pour récupérer le contenu du fichier de liens. Pour cela, on utilisera le SDK AWS officiel :
composer require aws/aws-sdk-php
On va mettre à jour le code dans notre fonction qui lit le fichier depuis le système local afin de lire le fichier
depuis S3. On va instancier un client S3 pour pouvoir consulter le bucket et on va l'enregistrer en tant que
Stream Wrapper
pour pouvoir utiliser s3://
en tant que protocole d’accès aux fichiers du bucket lors de
l’utilisation des fonctions natives PHP de lecture de fichiers.
index.php
diff --git a/index.php b/index.php
--- a/index.php
+++ b/index.php
@@ -4,6 +4,7 @@
require __DIR__ . '/vendor/autoload.php';
+use Aws\S3\S3Client;
use Nyholm\Psr7\Response;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
@@ -12,13 +13,21 @@
use function Psl\Type\non_empty_dict;
use function Psl\Type\non_empty_string;
-return new class implements RequestHandlerInterface
+return new class($_ENV['BUCKET_NAME']) implements RequestHandlerInterface
{
+ public function __construct(private readonly string $bucketName) {}
+
public function handle(ServerRequestInterface $request): ResponseInterface
{
$path = $request->getUri()->getPath();
- $fileContent = file_get_contents('./links.json');
+ $client = new S3Client([
+ 'region' => 'eu-west-3',
+ 'version' => '2006-03-01'
+ ]);
+ $client->registerStreamWrapper();
+
+ $fileContent = file_get_contents(sprintf('s3://%s/links.json', $this->bucketName));
if (false === $fileContent) {
throw new RuntimeException('The file "links.json" is missing.');
}
Et voilà, on lit désormais le fichier depuis S3 avec peu de modifications. Le nom du bucket est passé en argument de
notre fonction. Cela permet de configurer simplement le bucket de destination notamment lorsque l’on déploie notre
fonction sur différents stage
.
Il faut maintenant passer le nom de notre bucket créé avec Lift à notre fonction en modifiant la configuration.
serverless.yml
diff --git a/serverless.yml b/serverless.yml
--- a/serverless.yml
+++ b/serverless.yml
@@ -16,6 +16,8 @@
description: 'Redirect user to target URL'
layers:
- ${bref:layer.php-81}
+ environment:
+ BUCKET_NAME: ${construct:published-links.bucketName}
events:
- httpApi:
method: 'GET'
Il n’y a plus qu’à déployer la nouvelle version de notre fonction avec la commande serverless deploy
.
Et voilà, les visiteurs sont toujours redirigés comme avant mais le fichier de liens est désormais disponible en dehors de notre fonction.
Enregistrer de nouveaux liens
On va mettre en place une API pour permettre d’enregistrer un ou plusieurs liens.
L’API attendra une requête POST
avec un corps de requête au format JSON
contenant la
liste des liens.
[
"https://hephaist.io/blog/2023/03/03/creer-un-raccourcisseur-d-url-avec-bref-partie-2/",
"https://hephaist.io/mentions-legales/"
]
L’API retournera un code HTTP
200 pour indiquer que la requête a été traité et un objet
JSON
avec les liens raccourcis respectifs dans le corps de réponse.
{
"https://hephaist.io/blog/2023/03/03/creer-un-raccourcisseur-d-url-avec-bref-partie-2/": "https://link.test/K0tbl20D",
"https://hephaist.io/mentions-legales/": "https://link.test/ECuA1hjC"
}
On va d’abord mettre en place une nouvelle fonction Lambda nommée entrypoint
pour recevoir la requête HTTP
et qui
retournera une réponse avec le code HTTP
200 et un objet JSON
vide en corps de réponse.
entrypoint.php
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use Nyholm\Psr7\Response;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
return new class implements RequestHandlerInterface
{
public function handle(ServerRequestInterface $request): ResponseInterface
{
return new Response(
status: 200,
headers: ['Content-Type' => 'application/json'],
body: \Psl\Json\encode(value: [], flags: \JSON_FORCE_OBJECT)
);
}
};
Ensuite, on va enregistrer notre fonction dans notre application pour que la fonction soit appelée lorsqu’une requête
HTTP
est effectuée sur /links
avec la méthode POST
.
serverless.yml
diff --git a/serverless.yml b/serverless.yml
--- a/serverless.yml
+++ b/serverless.yml
@@ -11,6 +11,16 @@
- ./vendor/bref/bref
functions:
+ entrypoint:
+ handler: entrypoint.php
+ description: 'API to register one or more links'
+ layers:
+ - ${bref:layer.php-81}
+ events:
+ - httpApi:
+ method: 'POST'
+ path: '/links'
+
redirect:
handler: index.php
description: 'Redirect user to target URL'
On va utiliser à nouveau la librairie PSL afin de traiter la requête pour transformer le tableau JSON
en liste
typée avant de valider que tous les liens sont des URL valides.
entrypoint.php
diff --git a/entrypoint.php b/entrypoint.php
--- a/entrypoint.php
+++ b/entrypoint.php
@@ -5,18 +5,53 @@
require __DIR__ . '/vendor/autoload.php';
use Nyholm\Psr7\Response;
+use Psl\Json\Exception\DecodeException;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
+use function Psl\Json\encode;
+use function Psl\Json\typed;
+use function Psl\Type\non_empty_string;
+use function Psl\Type\non_empty_vec;
return new class implements RequestHandlerInterface
{
public function handle(ServerRequestInterface $request): ResponseInterface
{
+ $errors = [];
+ try {
+ $links = typed(
+ $request->getBody()->getContents(),
+ non_empty_vec(
+ non_empty_string()
+ )
+ );
+ } catch (DecodeException $error) {
+ return new Response(
+ status: 400,
+ headers: ['Content-Type' => 'application/json'],
+ body: encode(['errors' => [$error->getMessage()]])
+ );
+ }
+
+ foreach($links as $link) {
+ if (false === filter_var($link, FILTER_VALIDATE_URL)) {
+ $errors[] = sprintf('Link "%s" is not a valid URL.', $link);
+ }
+ }
+
+ if (!empty($errors)) {
+ return new Response(
+ status: 400,
+ headers: ['Content-Type' => 'application/json'],
+ body: encode(['errors' => $errors])
+ );
+ }
+
return new Response(
status: 200,
headers: ['Content-Type' => 'application/json'],
- body: \Psl\Json\encode(value: [], flags: \JSON_FORCE_OBJECT)
+ body: encode(value: [], flags: JSON_FORCE_OBJECT)
);
}
};
Maintenant que l’on est assuré de recevoir une requête HTTP
avec uniquement des liens valides, il est temps
d’enregistrer nos nouveaux liens raccourcis. On va stocker les liens dans une base de données afin de pouvoir y inclure
plus d’informations, par exemple, si le lien est désactivé, le nombre de consultations, etc.
Pour se faire, on va utiliser le service AWS DynamoDB qui permet d’avoir une base
de données NoSQL à bas coût. On va utiliser à nouveau le plugin Lift pour créer
notre base de données que l’on va nommer links
.
serverless.yml
diff --git a/serverless.yml b/serverless.yml
--- a/serverless.yml
+++ b/serverless.yml
@@ -14,6 +14,8 @@
entrypoint:
handler: entrypoint.php
description: 'API to register one or more links'
+ environment:
+ TABLE_NAME: ${construct:links.tableName}
layers:
- ${bref:layer.php-81}
events:
@@ -36,6 +38,8 @@
constructs:
published-links:
type: storage
+ links:
+ type: database/dynamodb-single-table
# Exclude files from deployment
package:
Notre base de données a été pré-configurée par Lift notamment avec 2 attributs :
- PK
- C’est la clé d’identification d’un enregistrement. On générera un UUID v5 à partir de l’adresse de destination afin d’obtenir un identifiant prédictible.
- SK
- Cette clé permettra de définir comment trier nos enregistrements. On va utiliser le lien de destination.
Pour générer un lien, il est nécessaire de définir quel est le domaine utilisé pour construire le lien. Grâce à une
variable d’environnement déclarée dans le fichier de configuration serverless.yml
, on va passer à notre fonction le
domaine à utiliser.
serverless.yml
diff --git a/serverless.yml b/serverless.yml
--- a/serverless.yml
+++ b/serverless.yml
@@ -16,6 +16,7 @@
description: 'API to register one or more links'
environment:
TABLE_NAME: ${construct:links.tableName}
+ DOMAIN_NAME: 'https://link.test'
layers:
- ${bref:layer.php-81}
events:
Afin de générer un UUID v5, on va utiliser le package symfony/uid. Pour générer le lien raccourci, on utilisera le package hidehalo/nanoid-php.
composer require symfony/uid hidehalo/nanoid-php
Pour effectuer l’enregistrement de nos liens dans DynamoDB, on va utiliser à nouveau le SDK AWS. Il est possible d’écrire un enregistrement à la fois avec la méthode putItem ou plusieurs enregistrements avec batchWriteItem. C’est cette dernière méthode que l’on va utiliser.
entrypoint.php
diff --git a/entrypoint.php b/entrypoint.php
--- a/entrypoint.php
+++ b/entrypoint.php
@@ -4,18 +4,28 @@
require __DIR__ . '/vendor/autoload.php';
+use Aws\DynamoDb\DynamoDbClient;
+use Hidehalo\Nanoid\Client;
use Nyholm\Psr7\Response;
use Psl\Json\Exception\DecodeException;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
+use Symfony\Component\Uid\Uuid;
use function Psl\Json\encode;
use function Psl\Json\typed;
use function Psl\Type\non_empty_string;
use function Psl\Type\non_empty_vec;
-return new class implements RequestHandlerInterface
+return new class($_ENV['TABLE_NAME'], $_ENV['DOMAIN_NAME']) implements RequestHandlerInterface
{
+ private const NS_ID = '7c1a90e3-de46-48cb-811b-06d42dde7524';
+
+ public function __construct(
+ private readonly string $linksTableName,
+ private readonly string $domainName
+ ) {}
+
public function handle(ServerRequestInterface $request): ResponseInterface
{
$errors = [];
@@ -48,6 +58,41 @@
);
}
+ $dbClient = new DynamoDbClient(['region' => 'eu-west-3', 'version' => '2012-08-10']);
+ $shortIdGenerator = new Client(size: 8);
+
+ $putItemRequests = [];
+ foreach ($links as $target) {
+ // Générer le lien raccourci
+ $source = sprintf('%s/%s', $this->domainName, $shortIdGenerator->generateId());
+
+ // Générer un UUID prédictible à partir du lien de destination
+ $linkId = Uuid::v5(namespace: Uuid::fromString(self::NS_ID), name: $target);
+
+ // Préparer la requête d'enregistrement dans DynamoDB
+ $putItemRequests[] = [
+ 'PutRequest' => [
+ 'Item' => [
+ // Champs pré-configurés par Lift
+ 'PK' => ['S' => $linkId], // Clé primaire
+ 'SK' => ['S' => $target], // Clé de tri
+
+ // Attribut de l'enregistrement
+ 'linkId' => ['S' => $linkId],
+ 'target' => ['S' => $target],
+ 'source' => ['S' => $source]
+ ]
+ ]
+ ];
+ }
+
+ // Écrire les enregistrements dans DynamoDB
+ $dbClient->batchWriteItem([
+ 'RequestItems' => [
+ $this->linksTableName => $putItemRequests
+ ]
+ ]);
+
return new Response(
status: 200,
headers: ['Content-Type' => 'application/json'],
Maintenant que nos liens sont enregistrés en base de données, il faut retourner les liens raccourcis à l’utilisateur dans la réponse de l’API.
entrypoint.php
diff --git a/entrypoint.php b/entrypoint.php
--- a/entrypoint.php
+++ b/entrypoint.php
@@ -61,6 +61,7 @@
$dbClient = new DynamoDbClient(['region' => 'eu-west-3', 'version' => '2012-08-10']);
$shortIdGenerator = new Client(size: 8);
+ $generatedLinks = [];
$putItemRequests = [];
foreach ($links as $target) {
// Générer le lien raccourci
@@ -84,6 +85,8 @@
]
]
];
+
+ $generatedLinks[$target] = $source;
}
// Écrire les enregistrements dans DynamoDB
@@ -96,7 +99,7 @@
return new Response(
status: 200,
headers: ['Content-Type' => 'application/json'],
- body: encode(value: [], flags: JSON_FORCE_OBJECT)
+ body: encode(value: $generatedLinks, flags: JSON_FORCE_OBJECT)
);
}
};
On peut déployer notre nouvelle API avec sa base de données avec la commande
serverless deploy
.
On a maintenant une API pour enregistrer des liens dans une base de données.
HTTP
d’enregistrement de liens et
d’exécuter l’enregistrement en base de données, il sera possible de paralléliser le traitement des
enregistrements par l’utilisation d’un bus de commande.
Mettre à jour le fichier de liens
A ce stade, on enregistre de nouveaux liens en base de données. Cependant, ils ne sont pas enregistrés dans notre
fichier JSON
sur S3.
On pourrait mettre à jour la liste des liens sur S3 en même temps qu’on les enregistre en base de données. Toutefois, notre API peut être appelée par plusieurs utilisateurs en simultanés ce qui peut provoquer des problèmes d’exécutions concurrentes.
Pour résoudre cette problématique, nous allons :
- lever un événement pour notifier que l’on a enregistré un lien
- créer une fonction
update-short-links
réagissant à l’événement pour mettre à jour le fichierJSON
- configurer l'exécution de cette nouvelle fonction pour qu’elle ne puisse s’exécuter qu’une seule fois en simultané
AWS met à disposition le service Amazon EventBridge qui permet de créer des bus de messages pouvant être exploités par des services AWS ou par n’importe quelle application.
On va modifier notre fonction d’enregistrement de liens afin de lever un événement personnalisé dans le bus par défaut du service EventBridge. Pour construire cet événement, le service demande au minimum 3 informations :
- detail
- C’est un objet JSON pouvant contenir les informations relatives à l’événement. On y mettra le lien raccourci et le lien cible.
- detail-type
- C’est un identifiant du type d’événement. On utilisera
LinkWasRegistered
. - source
- C’est un identifiant de la source émettrice de l’événement. On utilisera
demo-link-shortener.entrypoint
.
Toujours grâce au SDK AWS, on va envoyer un événement à EventBridge pour chacun des liens enregistrés. On enverra les événements en lot même s'il est possible également de les envoyer unitairement.
entrypoint.php
diff --git a/entrypoint.php b/entrypoint.php
--- a/entrypoint.php
+++ b/entrypoint.php
@@ -5,6 +5,7 @@
require __DIR__ . '/vendor/autoload.php';
use Aws\DynamoDb\DynamoDbClient;
+use Aws\EventBridge\EventBridgeClient;
use Hidehalo\Nanoid\Client;
use Nyholm\Psr7\Response;
use Psl\Json\Exception\DecodeException;
@@ -63,6 +64,7 @@
$generatedLinks = [];
$putItemRequests = [];
+ $events = [];
foreach ($links as $target) {
// Générer le lien raccourci
$source = sprintf('%s/%s', $this->domainName, $shortIdGenerator->generateId());
@@ -86,6 +88,14 @@
]
];
+ $events[] = [
+ 'source' => 'demo-link-shortener.entrypoint',
+ 'detail-type' => 'LinkWasRegistered',
+ 'detail' => [
+ 'source' => $source,
+ 'target' => $target
+ ]
+ ];
$generatedLinks[$target] = $source;
}
@@ -96,6 +106,9 @@
]
]);
+ $eventBridgeClient = new EventBridgeClient(['region' => 'eu-west-3', 'version' => '2015-10-07']);
+ $eventBridgeClient->putEvents(['Entries' => $events]);
+
return new Response(
status: 200,
headers: ['Content-Type' => 'application/json'],
Pour que notre fonction puisse publier l’événement dans le bus EventBridge, nous allons devoir ajouter une permission pour l’autoriser à effectuer l’action. Grâce à Serverless framework, on peut la déclarer dans le fichier de configuration.
serverless.yml
diff --git a/serverless.yml b/serverless.yml
--- a/serverless.yml
+++ b/serverless.yml
@@ -5,6 +5,12 @@
region: eu-west-3
runtime: provided.al2
deploymentMethod: direct # fastest deployment method
+ iam:
+ role:
+ statements:
+ - Effect: Allow
+ Action: events:PutEvents
+ Resource: '*'
plugins:
- serverless-lift
La prochaine étape est de mettre en place la fonction update-short-links
qui va traiter l'événement d’enregistrement
pour mettre à jour le lien. Bref nous met à disposition une classe EventBridgeHandler
pour
faciliter le traitement des événements EventBridge.
update-short-links.php
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use Bref\Context\Context;
use Bref\Event\EventBridge\EventBridgeEvent;
use Bref\Event\EventBridge\EventBridgeHandler;
return new class extends EventBridgeHandler
{
public function handleEventBridge(EventBridgeEvent $event, Context $context): void
{
['source' => $source, 'target' => $target] = $event->getDetail();
}
};
Comme pour la fonction de redirection, on va avoir besoin de lire le fichier sur S3 avec le SDK AWS mais aussi de le remplacer par la version mise à jour avec le nouveau lien. On utilisera la fonction parse_url pour récupérer uniquement le chemin de l’URL.
update-short-links.php
diff --git a/update-short-links.php b/update-short-links.php
--- a/update-short-links.php
+++ b/update-short-links.php
@@ -7,11 +7,36 @@
use Bref\Context\Context;
use Bref\Event\EventBridge\EventBridgeEvent;
use Bref\Event\EventBridge\EventBridgeHandler;
+use function Psl\Json\encode;
+use function Psl\Type\dict;
-return new class extends EventBridgeHandler
+return new class($_ENV['BUCKET_NAME']) extends EventBridgeHandler
{
+ public function __construct(private readonly string $bucketName) {}
+
public function handleEventBridge(EventBridgeEvent $event, Context $context): void
{
['source' => $source, 'target' => $target] = $event->getDetail();
+
+ $client = new S3Client(['region' => 'eu-west-3', 'version' => '2006-03-01']);
+ $client->registerStreamWrapper();
+
+ $filePath = sprintf('s3://%s/links.json', $this->bucketName);
+ $fileContent = file_get_contents($filePath);
+ if (false === $fileContent) {
+ $fileContent = '{}'; // Le fichier n'existe pas encore, on initialise à vide notre liste de liens.
+ }
+
+ $registeredLinks = typed(
+ $fileContent,
+ dict(
+ non_empty_string(),
+ non_empty_string()
+ )
+ );
+
+ $registeredLinks[parse_url($source, PHP_URL_PATH)] = $target;
+
+ file_put_contents($filePath, encode(value: $registeredLinks, flags: JSON_FORCE_OBJECT));
}
};
Notre fonction est prête à recevoir les événements. Il faut maintenant indiquer qu’elle écoute l’événement qu’on a
précédemment créé. Pour cela, il faut déclarer la fonction dans le fichier de configuration serverless.yml
et
indiquer qu’elle écoute les événements dans EventBridge et notamment celui qu’on envoie. Pour limiter le nombre
d’exécutions simultanées, on va définir l’option reservedConcurrency
à 1 afin qu’il n’y ait pas d’exécution
concurrente de la fonction qui met à jour le fichier sur S3.
serverless.yml
diff --git a/serverless.yml b/serverless.yml
--- a/serverless.yml
+++ b/serverless.yml
@@ -30,6 +30,19 @@
method: 'POST'
path: '/links'
+ update-short-links:
+ handler: update-short-links.php
+ description: 'Update the list of redirected short links'
+ layers:
+ - ${bref:layer.php-81}
+ environment:
+ BUCKET_NAME: ${construct:published-links.bucketName}
+ reservedConcurrency: 1
+ events:
+ - eventBridge:
+ pattern:
+ detail-type: ['LinkWasRegistered']
+
redirect:
handler: index.php
description: 'Redirect user to target URL'
Il ne reste qu’à déployer notre fonction avec la commande serverless deploy
afin que le fichier soit mis à jour
lorsque l’on enregistrera un nouveau lien.
Conclusion
Notre raccourcisseur d’URL est maintenant complètement fonctionnel en permettant l’enregistrement de liens raccourcis et de gérer la redirection vers l’adresse de destination.
En se basant sur les services AWS disponibles et Bref, on a un raccourcisseur d’URL avec les coûts suivants pour environ 50 000 appels mensuels :
Service AWS | Coût mensuel | Coût annuel |
---|---|---|
DynamoDB | 0,13 $ | 1,56 $ |
S3 | 0,07 $ | 0,84 $ |
EventBridge | 0,06 $ | 0,72 $ |
API Gateway | 0,06 $ | 0,72 $ |
Route 53 | 0,52 $ | 6,24 $ |
Lambda | 0,00 $ | 0,00 $ |
Total | 0,84 $ | 10,11 $ |
À titre de comparaison, il faut compter environ 8 à 10 $ / mois avec un abonnement à un service en ligne de raccourcisseurs d'URL. En concevant son propre raccourcisseur, on économise sur le coût et on reste maître de l'utilisation des données.
AWS propose un certain nombre de services avec lesquels on aurait pu avoir une approche différente. On pourrait par exemple utiliser API Gateway ou S3/Cloudfront en mode hébergement de site statique pour réaliser la redirection. De même, au lieu de lire le fichier depuis S3, on aurait pu faire en sorte de compiler une nouvelle version de la fonction en embarquant la dernière version du fichier de liens disponible afin de n’accéder à S3 qu’au moment de la compilation.
Avec ces 2 articles, vous avez désormais les clés pour concevoir un raccourcisseur d'URL et également d'y ajouter par exemple une API pour désactiver des liens ou mettre en place le suivi du nombre de visites d’un lien raccourci.