01Aperçu du projet
keepix.cloud est un hôte de médias pour des produits qui doivent servir les fichiers d'autres personnes : photos de catalogue dans une vitrine, images d'avis dans un marché, vidéo de visite dans une application. Vous envoyez l'original dans une demande signée, et la réponse contient déjà les adresses finies — un ensemble nommé de variantes WebP pour une image, une échelle HLS pour une vidéo. Les fichiers sont servis depuis le sous-domaine propre du client, donc le lecteur voit sa marque et ne nous voit jamais.
Le principe est que les médias ne sont pas une fonctionnalité que vous construisez une fois par projet. Chaque produit qui permet aux gens de télécharger quelque chose finit par écrire la même chose encore et encore : redimensionnement, conversion de format, un schéma de nommage, une politique de cache, suppression des métadonnées, un chemin pour tout supprimer à propos de cette personne. Écrit une cinquième fois, c'est mal écrit une cinquième fois — et les parties qui vont mal (une balise GPS divulguée, un SVG qui s'est avéré être un script) échouent silencieusement, sans erreur et sans ligne de journal.
Alors nous avons construit le service autour d'une idée : l'adresse est déclarée par le service et stockée par le client, jamais calculée du côté du client. Cette décision unique supprime la manière la plus courante dont les intégrations de médias échouent — une page qui se rend parfaitement avec un trou là où la photo du produit devrait être.
Nous avons conçu et construit l'ensemble du produit : le pipeline d'entrée, le modèle de variante, l'échelle vidéo, le modèle multi-locataire avec ses propres domaines et clés de signature, la facturation au compteur, le tableau de bord, le contrat API public et la documentation. Ci-dessous, quel problème cela résout, comment cela est assemblé, et quelles décisions d'ingénierie nous prendrions de la même manière à nouveau.
02Contexte et le problème
Stocker une image téléchargée est facile. Maintenir un chemin média qui reste correct pendant des années, sous charge, à travers plusieurs produits et les fichiers d'autres personnes, ne l'est pas. Lorsque nous avons déballé la tâche, les pièges sont rapidement apparus.
- Des largeurs arbitraires sont un piège.Une URL comme
?w=473semble flexible et représente en fait deux problèmes à la fois : un cache qui ne se réchauffe jamais, car chaque page demande un nombre légèrement différent, et un moyen gratuit pour quiconque d'occuper le processeur en demandant mille largeurs d'affilée. - Une adresse calculée se brise silencieusement.La règle "id → shard → path", intégrée dans le code du client, survit exactement jusqu'au premier changement de mise en page de l'autre côté. Ensuite, la page se rend toujours et le produit a simplement un trou là où sa photo était — pas d'erreur, rien dans le journal.
- Les métadonnées sont une fuite que personne ne remarque.Les coordonnées GPS de la maison de quelqu'un présentes dans les EXIF d'une photo d'avis ne déclenchent aucune erreur, ne cassent aucune page et n'atteignent aucune surveillance. C'est seulement une fuite quand quelqu'un regarde.
- SVG n'est pas une image.C'est un balisage exécutable. Accepté comme une image et servi depuis le propre domaine du client, un script à l'intérieur s'exécute au nom de ce domaine.
- La suppression doit être prouvable.Une demande d'effacement GDPR répondue par le marquage des lignes comme supprimées alors que les octets restent sur le disque est une suppression qui ne s'est pas produite.
- La vidéo est un ensemble, pas un fichier.Un téléchargement doit devenir une échelle jouable, un cadre d'affiche et un secours — et rien de tout cela ne peut se produire à l'intérieur de la demande qui a accepté le fichier.
- La facturation doit être honnête pour de petits montants.Un gigaoctet peut coûter moins d'un centime ; arrondir à des centimes entiers engloutit toute la facture mesurée et rend la facture fictive.
Il y avait une exigence de plus, et elle a façonné tout le design : le service ne doit pas sortir sur Internet du tout. Un hôte multimédia qui récupère une image à partir d'une adresse tierce au nom du client sait qui a demandé quoi et transmet cette connaissance à quel que soit le CDN qu'il a utilisé. keepix ne connaît aucune adresse tierce, et c'est une propriété du code, pas une promesse sur la page de tarification.
03Objectifs du projet
La tâche s'est transformée en une liste d'objectifs que nous avons maintenus à chaque étape :
- Une demande entrée, des adresses terminées sorties. Le client envoie l'original et reçoit immédiatement les adresses à stocker — pas de deuxième appel, pas d'attente pour qu'un travail se termine pour les images.
- Un ensemble nommé et fini de variantes. Trois largeurs pour les images et quatre formes pour la vidéo, déclarées par type de fichier, afin que le cache soit chaud et que le processeur ne soit pas à louer.
- Le domaine propre du client. Fichiers servis depuis
img.leurdomaine, avec le service invisible dans la barre d'adresse. - Un cache qui peut être conservé indéfiniment. L'adresse contient un hachage du contenu, donc remplacer un fichier change son adresse et atteint le lecteur immédiatement.
- Sécurité intégrée dans le chemin. Type déterminé par l'analyse, un scan de virus qui refuse plutôt que de laisser passer, ré-encodage sur chaque image, métadonnées supprimées, SVG refusé aux deux extrémités.
- Effacement prouvable. Une demande par le propre
owner_ref, et une réponse qui indique combien d'objets et de fichiers ont été envoyés. - Multi-location avec une véritable isolation.Propre domaines, propres types et variantes, propres plafonds, deux clés de signature pour que la rotation ne soit pas un temps d'arrêt.
- Facturation à la consommation que vous pouvez vérifier.Stockage en tant que moyenne plutôt qu'en tant que pic, trafic en tant que octets réellement livrés, opérations comptées une par une — décomposées par jour dans le tableau de bord.
- Une API qui admet ce qu'elle a fait.Chaque réponse indique ce qui a été créé et ce qui a été ignoré, et il y a un point de terminaison de réconciliation sec pour vérifier une migration par lots.
04Ce que nous avons fait
keepix se divise en quelques morceaux clairs, chacun ayant une tâche :
- Intake.Un point de terminaison signé accepte l'original avec son type, sa clé et la liste des variantes souhaitées. Les images reviennent prêtes dans la même réponse ; la vidéo va dans une file d'attente et la réponse le dit.
- Le pipeline de traitement.Détection de type, analyse de virus, ré-encodage, suppression des métadonnées, construction de variantes — dans un ordre fixe qui ne peut pas être sauté par demande.
- Livraison.Un hôte séparé sans sessions, sans JavaScript et sans
Set-Cookie, servant des fichiers directement depuis le disque avec un cache immuable d'un an. - L'API du locataire.Signé avec HMAC-SHA256, avec des points de terminaison pour résoudre des adresses, réconcilier par lots, exporter un inventaire, supprimer un objet et effacer tout ce qui appartient à une personne.
- Le tableau de bord.Dossiers, glisser-déposer, recherche par titre, description et étiquettes — et utilisation décomposée par jour. Cela fonctionne entièrement sans JavaScript ; le script ajoute de la commodité, pas la capacité de travailler.
- Facturation.Forfaits plus dépassement mesuré, maintenu en centièmes de cent, avec l'admission s'arrêtant plutôt que de dépenser silencieusement de l'argent sur le plan gratuit.
- Le stock.Une couche de marché où les locataires peuvent acheter et vendre leur propre travail, partageant le même stockage et le même chemin de livraison.
Tout ce qui suit est un aperçu plus détaillé des décisions à l'intérieur de ces pièces — celles qui seraient coûteuses à changer plus tard.
05Architecture de la solution
Le service est trois espaces avec points d'entrée physiquement séparés, et cette séparation est l'épine dorsale de tout le design :
- Livraison publique — pas d'API du tout. Le serveur web recherche le fichier sur le disque et le sert. Non trouvé signifie 404, pas "générer à la volée". Il n'y a pas de code exécutable sur ce chemin, c'est pourquoi l'hôte de livraison peut porter
default-src 'none'; sandboxet le signifier. - L'API privée du locataire. Chaque requête signée ; la signature couvre la méthode, le chemin avec sa chaîne de requête, le timestamp et un hachage du corps. Signer le chemin sans la requête laisserait
genreetclénon signé — échangeable, et personne ne le remarquerait. - L'API admin pour le panneau de contrôle, sur son propre point d'entrée avec ses propres identifiants.
Les réponses sont toujours en JSON et toujours en anglais, avec une formulation par code de refus — donc le même échec se lit de la même manière dans le journal de chaque client, quelle que soit la langue de leur produit.
À l'intérieur, le stockage se divise en un arbre froid contenant des originaux, qui n'est jamais servi vers l'extérieur, et l'arbre servi de variantes. Conserver l'original est ce qui rend une nouvelle variante possible un an plus tard sans demander au client de télécharger quoi que ce soit à nouveau — et c'est aussi pourquoi "nous ne servons pas le fichier que vous avez envoyé" peut être une règle absolue plutôt qu'une règle habituelle.
06La vie d'un fichier
Un fichier passe par une séquence fixe, et l'ordre est le point :
- Le type est déterminé par l'analyse — à partir du contenu, pas de l'extension et pas de ce que le client dit que c'est. L'extension du fichier de sortie est à la charge du service.
- Le scan de virus s'exécute, et il peut refuser. Si le scanner est inaccessible, l'entrée répond
503au lieu de laisser passer le fichier. Passer un fichier silencieusement pendant que la vérification est en panne est un mensonge sur le travail effectué, et c'est le genre de mensonge qui ne refait surface que beaucoup plus tard. - L'image est ré-encodée. Aucun octet du fichier qui est arrivé n'est jamais renvoyé.
- Les métadonnées ne survivent pas à la ré-encodage. EXIF et GPS sont perdus à cause de la façon dont le chemin est construit, pas parce que celui qui a téléchargé s'est souvenu de les supprimer.
- Les variantes sont construites et leurs adresses sont renvoyées dans la même réponse.
SVG n'est ni accepté ni servi — jamais, à l'entrée ou à la sortie. La vérification s'effectue deux fois, sur le type de contenu déclaré et sur les premiers octets du fichier, car pour SVG, un détecteur de type dira souvent simplement "texte". Ce qui est servi, c'est WebP, JPEG, PNG, MP4, une playlist HLS et ses segments ; tout le reste est un 415.
L'entrée est idempotente: le même sha256 sous la même clé ne refait pas le travail et renvoie les mêmes adresses. Les nouvelles tentatives après une connexion rompue sont donc gratuites, ce qui est important lorsque le fichier fait deux gigaoctets et que le réseau est un téléphone.
07Variantes nommées, pas des largeurs arbitraires
Les images ont trois largeurs nommées — miniature 400, carte 1000, pleine 1400, tous en WebP à qualité 82 — et vous demandez une variante par son nom. L'ensemble est fini et déclaré par type de fichier. C'est la décision sur laquelle repose tout le service, et cela élimine une classe de problèmes plutôt qu'un bug.
Deux règles régissent quand une variante peut légitimement ne pas apparaître, et les deux existent pour éviter de mentir au lecteur :
- Rien n'est étiré. Si l'original est plus étroit que la largeur de la variante, la variante reste à la taille de l'original et la réponse le dit honnêtement — les
wethchamps portent les vrais chiffres. Une copie agrandie ressemble à une faute du service, et ce serait le cas. - Les copies identiques ne sont pas stockées deux fois.Si deux largeurs produisent exactement le même fichier, la deuxième adresse n'est pas créée. Deux fichiers identiques en octets à deux adresses sont deux téléchargements de la même chose sur le téléphone de quelqu'un.
Ce qui signifie que la réponse doit être lue, pas supposée : vous pouvez demander deux variantes et en obtenir une, avec un sauté bloc expliquant pourquoi. Nous avons fait de cela une réponse normale et attendue plutôt qu'un cas marginal, car une intégration écrite contre la forme optimiste échoue sur la première petite image qu'un utilisateur télécharge.
Ajouter une nouvelle variante plus tard ne nécessite pas de re-télécharger quoi que ce soit : elle est construite à partir de l'original dans l'arbre froid. C'est la raison pour laquelle l'original est conservé.
08Vidéo : une échelle HLS, une affiche et un aperçu
Un téléchargement vidéo devient un ensemble, car c'est ce dont un lecteur a réellement besoin : un échelle HLS de jusqu'à trois niveaux de qualité (640, 1280 et 1920 px), un affiche pris à 10 % de la durée, un aperçu silencieux des premières secondes pour le survol et la lecture automatique dans le fil, et un MP4 comme solution de secours pour les anciens clients.
Une étape plus large que l'original n'est pas faite, pour la même raison qu'une image étirée ne l'est pas : une copie agrandie ressemble à une faute du service. L'affiche est prise à un dixième de la durée plutôt qu'au premier cadre, car le premier cadre d'une vraie vidéo est très souvent noir.
Le traitement vidéo ne se fait pas à l'intérieur de la requête qui a accepté le fichier — il va dans une file d'attente, et la réponse le dit. La réponse d'admission est honnête sur les parties qui sont prêtes maintenant et celles qui sont en attente, afin qu'un client puisse stocker ce qu'il a et demander à nouveau plus tard plutôt que de bloquer l'écran de téléchargement d'un utilisateur lors d'une transcodage.
09Votre propre domaine et un cache éternel
Les fichiers sont servis depuis le sous-domaine propre du locataire — img.leurdomaine — que le locataire pointe vers le service avec un enregistrement A. Le lecteur voit sa marque et son adresse, et ne voit pas du tout keepix. Dans le plan gratuit, le domaine est partagé ; les deux routes fonctionnent de la même manière.
Un locataire peut connecter autant de domaines qu'il le souhaite mais exactement un canonique un, et cette contrainte est délibérée : avec deux domaines canoniques, un fichier obtient deux adresses, ce qui signifie deux caches et les mêmes octets téléchargés deux fois sur le même téléphone de lecteur.
Les en-têtes de livraison sont les mêmes pour chaque locataire et ne changent pas : une durée d'un an immuable cache, nosniff, default-src 'none'; sandbox, une politique CORS permissive pour la lecture, et pas un seul Set-Cookie. Le cache éternel est sûr précisément parce que l'adresse porte un hachage du contenu: changez les octets et l'adresse change avec eux, donc une image remplacée atteint le lecteur immédiatement au lieu d'attendre un TTL.
Et c'est exactement pourquoi l'adresse ne peut pas être calculée du côté du client. Elle est renvoyée par le service, stockée à côté de l'enregistrement auquel elle appartient, et demandée à nouveau via résoudre si elle est jamais perdue.
10Intégration : type, analyse de virus, métadonnées
Tout sur le service est un fichier qu'une personne a envoyé — une photo dans un avis, une vidéo de walkthrough. Les règles d'admission sont écrites pour leur bien plutôt que pour la forme, et chacune d'elles existe parce que l'alternative échoue discrètement.
Déterminer le type par analyse plutôt que par extension n'est pas de la pédanterie : l'extension est la seule chose qu'un téléchargeur contrôle entièrement.Refuser lorsque le scanner est hors service coûte en disponibilité et achète la garantie que "scanné" signifie scanné.Réencoder chaque image signifie qu'un fichier élaboré n'atteint jamais un lecteur dans sa forme originale.Suppression des métadonnées lors de ce ré-encodage signifie qu'il ne peut pas être oublié.
Du côté de la livraison, les garanties sont structurelles plutôt que procédurales. L'hôte de livraison n'a pas de sessions, pas de JavaScript et pas de code exécutable sur le chemin ; le contenu sort avec une politique de sécurité de contenu qui empêcherait un navigateur d'exécuter quoi que ce soit même si quelque chose de dangereux était entré. Deux couches indépendantes, car les échecs intéressants sont ceux où la première couche était mal configurée et personne ne l'a remarqué.
Le journal de livraison, avec les adresses des lecteurs, vit 24 heures. Rien dans le service n'en a besoin plus longtemps, ce qui rend sa conservation plus longue une simple accumulation des traces des autres.
11Effacer tout sur une personne
Chaque objet porte un owner_ref — peu importe comment le locataire appelle le propriétaire de ce fichier. Pour les images de catalogue, il est vide : elles ne concernent pas une personne. Pour les photos d'avis et les vidéos des utilisateurs, il est requis.
Une demande efface tout ce qui est en dessous, et la réponse nomme un nombre: combien d'objets et combien de fichiers ont été envoyés. Ce nombre est le point de terminaison. Une porte de données personnelles devrait vérifier l'exécution, pas l'intention — une ligne marquée comme supprimée alors que les octets sont toujours sur le disque est une suppression qui ne s'est pas produite, et elle continuera de ne pas se produire jusqu'à ce que quelqu'un regarde.
L'effacement supprime les enregistrements et les octets en même temps plutôt que selon un calendrier, et il emporte les copies différées des versions antérieures avec lui. C'est aussi ce qui rend keepix utilisable à partir d'un produit ayant ses propres obligations GDPR : un flux de suppression dans le code du client peut l'appeler en ligne et lire le compte, au lieu de faire confiance à un travail de nettoyage quelque part pour s'en occuper.
Les clés de signature fonctionnent de la même manière.Un locataire a toujours deux clés en usage, car avec une clé, la rotation signifie un temps d'arrêt — et le temps d'arrêt est la raison pour laquelle la rotation est reportée indéfiniment. Le secret est montré une fois à l'émission et n'est jamais rendu au panneau de contrôle : pouvoir signer une demande est le droit d'écrire dans le stockage de quelqu'un d'autre.
12Une API signée et réconciliation
Chaque demande privée porte quatre en-têtes — locataire, identifiant de clé, horodatage et signature — et la signature est HMAC-SHA256 sur la méthode, le chemin complet avec la requête, l'horodatage et le hachage du corps. La fenêtre est de 300 secondes. Une demande signée identique répétée dans la même seconde est refusée comme une répétition, ce qui est la protection qui fonctionne comme prévu, et le contrat le dit clairement au lieu de laisser les intégrateurs le découvrir.
L'ensemble des points de terminaison est petit et chacun répond à une véritable question opérationnelle :
mettre— accepter un original ;mettre-variant— accepter une copie déjà terminée sans la réencoder, pour transférer ce qu'un client a déjà. Réencoder une copie terminée signifie perdre de la qualité pour rien.résoudreetrésoudre-lot(jusqu'à 1000 clés) — quelles adresses cette clé a. C'est un outil de réparation : si un enregistrement est perdu, vous demandez plutôt que de deviner.réconcilier— une vérification à sec, jusqu'à 1000 enregistrements à la fois, qui ne change rien et répondok/manquant/incohérence/en attentepar enregistrement plus un résumé du lot.inventaire— l'exportation qui effectue la comparaison dans l'autre sens, la liste du service contre celle du client, paginée par la clé elle-même afin que la page ne glisse pas pendant que les éléments sont acceptés en cours de route.objet,effacer,quota,ping, et un non signéhealthzqui indique que le front-end est vivant et rien de plus — pas de version, pas d'état de base de données.
La réconciliation mérite sa propre note, car c'est le point de terminaison qui justifie l'ensemble du contrat. Après une grande migration, il n'y a qu'une seule question qui compte : tout est-il passé ? Y répondre un fichier à la fois signifie autant de requêtes qu'il y a de fichiers, donc personne ne le fait — et ensuite une migration est déclarée terminée sur la base du fait que le script de téléchargement n'a pas planté. La réconciliation par lots rend la réponse honnête suffisamment bon marché pour être réellement obtenue.
13Tableau de bord, utilisation et facturation
Le tableau de bord est une bibliothèque sans aucun code : dossiers, glisser-déposer des fichiers avec la souris, recherche par titre, description et tags. Il fonctionne entièrement sans JavaScript — le script ajoute de la commodité, pas la capacité de travailler. Ce n'est pas de la nostalgie ; c'est le moyen le moins cher de garantir que le panneau reste utilisable sur une mauvaise connexion et reste testable sans moteur de navigateur.
L'utilisation est comptée depuis le début du mois et décomposée par jour : combien de stockage, combien de trafic de livraison et combien d'opérations sont tombées à chaque date, combien du paquet est consommé et ce qui est venu en plus. La décomposition compte plus que le total — une facture que vous ne pouvez pas attribuer à un jour est une facture avec laquelle vous ne pouvez pas discuter.
Trois décisions dans la facturation méritent d'être mentionnées :
- Le stockage est la moyenne sur la période, pas le pic.Un seul jour avec un gros téléchargement ne devrait pas facturer tout le mois.
- Le trafic de livraison est les octets réellement livrés, pris dans le journal du serveur — pas "taille du fichier × nombre de requêtes", ce qui surestime chaque requête de plage et chaque téléchargement abandonné.
- Les tarifs sont exprimés en centièmes de cent.Un gigaoctet peut coûter moins d'un cent ; arrondir à des centimes entiers mangerait toute la facture mesurée et transformerait discrètement la facture en fiction.
Dans le plan gratuit, il n'y a pas de facturation mesurée du tout : l'admission s'arrête au lieu de commencer silencieusement à dépenser l'argent du client. Un service qui décide de facturer quelqu'un qui n'a jamais entré de carte est un service que personne ne recommande deux fois.
14Pile technologique
Nous avons choisi la pile pour un service dont le chemin principal est un serveur web transférant un fichier :
- PHP 8.4 pour l'API et le panneau de contrôle — mature, suffisamment rapide sur ce chemin et peu coûteux à maintenir, ce qui est important pour un produit avec un niveau gratuit.
- Un hôte de livraison dédié servant directement depuis le disque, sans code d'application dans le chemin de la requête.
- WebP pour les images à qualité fixe, H.264 + AAC en HLS pour la vidéo avec un fallback MP4 progressif.
- Une file d'attente pour le travail vidéo, donc un transcodage ne se trouve jamais à l'intérieur d'une demande de téléchargement.
- HMAC-SHA256 signature de demande avec deux clés actives par locataire et une fenêtre de 300 secondes.
- Un arbre froid d'originaux en dehors du chemin servi, ce qui rend possibles de nouvelles variantes et reconstructions plus tard.
Le service est délibérément conservateur dans ce dont il dépend. Il ne fait aucune demande sortante de sa propre initiative, n'utilise aucun CDN tiers et ne conserve aucun enregistrement sur les utilisateurs du client au-delà du locataire, de la clé, du type, du nombre d'octets et des variantes. Chaque dépendance que vous n'avez pas est une dépendance qui ne peut pas casser vos médias un mardi.
15Design et UX
Le site public avait un seul objectif : rendre un produit d'infrastructure lisible pour l'ingénieur qui va réellement l'intégrer. Ainsi, le premier écran montre la vraie demande et la vraie réponse — les adresses revenant en JSON — plutôt qu'une abstraction de celles-ci. Un intégrateur décide en environ trente secondes si un service de médias correspond à son code, et il décide en regardant la forme de sa réponse.
Le reste du site est écrit de la même manière. Chaque capacité est énoncée avec sa contrainte : variantes nommées etpourquoi les largeurs arbitraires sont refusées ; un cache éterneletle hachage dans l'adresse qui le rend sûr ; un point de terminaison d'effacementetle numéro avec lequel il répond. Une documentation qui ne liste que ce qu'un service peut faire laisse le lecteur découvrir les limites en production.
Dans le tableau de bord, le même principe se transforme en la base sans JavaScript et la répartition de l'utilisation jour par jour : rien à l'écran que le lecteur ne puisse vérifier, et rien qui cesse de fonctionner lorsqu'un script échoue à se charger.
16Comment nous avons travaillé
Le projet s'est déroulé en étapes, chacune se terminant par quelque chose de démontrable :
- Contrat d'abord.Nous avons rédigé le contrat API — schéma de signature, points de terminaison, codes de refus, formes de réponse — avant l'implémentation, car le contrat est la partie contre laquelle les clients construisent et la partie qui est coûteuse à changer.
- Intégration et variantes.Le pipeline, dans son ordre fixe, avec les deux règles sur le non-étirement et le non-stockage de doublons intégrées dès le départ.
- Livraison.L'hôte séparé, l'ensemble d'en-têtes, l'adressage haché par contenu qui rend le cache éternel sûr.
- Vidéo.L'échelle, l'affiche et l'aperçu, et la file d'attente qui continue de transcoder à partir de la demande de téléchargement.
- Multi-location.Domaines, types, variantes, plafonds et le modèle de rotation à deux clés.
- Facturation et tableau de bord.Comptage mesuré avec une répartition jour par jour, puis l'interface utilisateur de la bibliothèque par-dessus.
- Une véritable migration.Nous avons déplacé un catalogue en direct sur le service et l'avons réconcilié par lots — c'est ainsi que le point de terminaison de réconciliation a pris sa forme.
Cette dernière étape valait plus que n'importe quel test interne. Déplacer des centaines de milliers de fichiers réels a révélé des choses qu'une suite de tests ne fait pas : des objets que le service a acceptés et perdus, des enregistrements dont l'adresse stockée avait dérivé, et la différence entre une vérification qui vérifie les hachages et une vérification qui confirme simplement qu'une ligne existe. Une vérification sans rien à vérifier rapporte un succès — nous avons donc fait en sorte que le mode faible indique dans quel mode il se trouve.
17Le résultat
Ce qui en est sorti est un hôte multimédia sur lequel un produit peut s'appuyer : une demande signée à l'entrée, des adresses finies à la sortie, servies depuis le domaine du client avec un cache qui peut être conservé indéfiniment.
- Variantes nommées et une échelle HLS, construites une fois et mises en cache pour toujours derrière une adresse hachée par le contenu.
- Le sous-domaine propre du client : le lecteur voit sa marque, pas la nôtre.
- Sécurité intégrée dans le chemin d'entrée — type analysé, refus de scan de virus, ré-encodage, métadonnées supprimées, SVG refusé aux deux extrémités.
- Effacement qui répond par un nombre, afin qu'une porte de données personnelles puisse vérifier l'exécution plutôt que l'intention.
- Multi-location avec ses propres domaines, ses propres plafonds et rotation à deux clés sans temps d'arrêt.
- Facturation au compteur maintenue en centièmes de cent, décomposée par jour, et un plan gratuit qui s'arrête plutôt que de dépenser.
18Leçons à retenir
keepix est un cas où la plupart de l'ingénierie a été consacrée à décider ce que le service ferait refuser de faire. Pas de largeurs arbitraires, pas d'adresses calculées, pas de SVG, pas de requêtes sortantes, pas de conservation des octets originaux sur le chemin servi, pas de facturation sur le plan gratuit. Chacune de ces suppressions élimine toute une classe d'échecs au lieu de gérer un.
La principale leçon que nous emporterons vers le prochain projet d'infrastructure : rendre la réponse honnête facile à obtenir. Réconciliation par lots, utilisation décomposée par jour, une effacement qui renvoie un compte, une réponse d'admission qui nomme ce qu'elle a sauté — dans tous les cas, l'alternative n'était pas une mauvaise réponse mais pas de réponse du tout, et pas de réponse est ce que les équipes acceptent silencieusement.
Si vous avez besoin d'un service multimédia sous votre propre domaine, d'un pipeline de fichiers qui doit être sécurisé avec les téléchargements d'autres personnes, ou d'un produit axé sur l'API où le contrat compte plus que les écrans, c'est le genre de travail que nous faisons de bout en bout.



