Blog

Tech · 27 octobre 2026 · 6 min

Meilisearch : sortir les filtres de l’app tierce

Un app proxy Shopify, un index Meilisearch chez nous et des webhooks pour la synchro : comment j’ai sorti les filtres d’une marketplace de 28 000 produits de l’app qui les gérait.

La semaine dernière était surtout là-dessus

La semaine dernière, j’ai passé l’essentiel de mon temps sur une seule chose. Sortir les filtres d’une marketplace de l’app qui les gérait.

Cette marketplace, c’est Castafiore. 28 000 produits, 17 000 en stock. Et une app tierce assise entre son catalogue et ses clients.

Je t’ai raconté la semaine dernière pourquoi ce genre d’app était devenu une surface d’attaque. Voilà le comment.

Ce que l’app faisait, et pourquoi elle devait partir

Elle gérait les filtres de collection. La marque, la taille, la couleur, le prix. Sur une collection de cette taille, le natif ne suffit pas. Shopify coupent les filtres au-delà de 5 000 produits. Donc tout le monde installe une app.

Sauf que cette app fait deux choses de trop. Elle injecte son JavaScript dans le front, là où tes clients achètent. Et elle garde l’index de tes produits sur ses serveurs, pas sur les tiens.

Le déclencheur du mois dernier n’est pas une certitude. L’app que je remplace n’est pas dans la liste des apps compromises d’octobre. Mais rien ne me dit qu’elle n’y sera pas le mois prochain.

Trois pièces, et aucune ne dépend d’un éditeur

L’app proxy : Shopify passent la main à Castapp

Le mécanisme tient en une phrase. Shopify prennent une URL de ta boutique, et la transmettent à l’app que tu contrôles. Ici, une route sous /apps, qui arrive sur Castapp, mon app Laravel.

Trois choses à savoir avant de se lancer.

  • Un seul proxy par app. Toutes les routes passent dessous.
  • Shopify signent chaque requête, et ajoutent la boutique et le préfixe dans l’URL. Ton app sait d’où vient l’appel.
  • Certains headers de la réponse sont retirés, dont Set-Cookie. Tu ne poses pas de session client depuis le proxy.

Meilisearch : l’index est chez nous

Meilisearch est un moteur de recherche open source. Un seul binaire, une API REST, et des documents que tu lui envoies.

Chez Castafiore, il tourne dans Castapp, pas comme un service à part. Les produits partent de la base, arrivent dans l’index, et le front interroge Castapp via le proxy.

Le point important n’est pas la vitesse. C’est que l’index t’appartient. Tu peux le vider, le reconstruire et changer de moteur sans demander la permission.

Ils annoncent des réponses sous 50 ms, même sur de gros index. Le gain que je constate est ailleurs : les filtres marchent sur les 28 000 produits, pas sur les 5 000 premiers.

Il sait aussi faire de la recherche hybride, mots et vecteurs. Si un jour la boutique veut du sémantique, la brique est déjà là.

Pourquoi lui et pas un service de recherche

Algolia est très bon et je n’ai rien contre. Sauf que c’est un service payant, et tu restes chez un tiers. Elasticsearch demande quelqu’un pour le tenir.

Meilisearch tient dans un binaire. Je le déploie avec l’app, je l’indexe depuis la base, et personne d’autre n’a la main dessus.

Le calcul est simple. Une app de filtres te coûte un abonnement et un accès. Un moteur que tu héberges te coûte du temps et une machine.

Les webhooks : la synchro

Un index qui se désynchronise est pire que pas d’index. Un produit en rupture qui reste filtrable, c’est un client qui clique dans le vide.

Shopify envoient un webhook à chaque création, mise à jour ou suppression de produit. Castapp le reçoit et met l’index à jour. Le stock suit par un autre webhook.

Deux webhooks pour la même modification, il faut que ça ne change rien. Sinon tu doubles des produits dans les filtres.

Le thème a dû suivre

Les filtres ne sont pas qu’une affaire de serveur. Le thème affiche les valeurs, les compteurs, et garde l’état dans l’URL.

J’ai modifié le thème pour brancher les nouvelles collections sur l’app proxy. Le JavaScript de l’app part, celui du thème prend sa place.

Et la règle reste la même, celle que je répète à chaque audit : le natif doit être la base. Ce que le thème sait faire, ne le donne pas à un tiers.

Ce qui a été pénible

Ma phrase de la semaine, telle quelle : « Tout est compliqué mais le dev était sympa à faire. »

Trois choses concrètement.

Les attributs filtrables se déclarent avant l’indexation. Un attribut oublié, et le filtre reste muet. Pas d’erreur, juste rien.

Les compteurs de facettes coûtent cher. Afficher le nombre de produits à côté de chaque valeur, sur 28 000 fiches, ça se calcule.

Et le piège que je surveille, c’est le SEO. Chaque combinaison de filtres fait une URL, et Google peut toutes les prendre. Autant ne pas remplacer un problème d’app par un problème de crawl.

La semaine a été chaude pour une autre raison. Deux CVE PHP sont sorties le 21 octobre : exécution de code à distance, sans authentification, score 9.2. Castapp tourne sur Laravel. Donc ça touchait tous mes clients d’un coup. Le message de PHP est clair, il n’y a pas de mitigation complète, la mise à jour est la seule option sûre.

Ce que ça change pour un e-commerçant

Un filtre n’est pas un produit. C’est une fonction de ton catalogue. Le jour où tu paies une app pour filtrer tes produits, tu loues l’accès à ton propre stock, et tu signes pour la surface d’attaque qui va avec.

La question à poser à ton prestataire tient en une ligne. Qui possède l’index de recherche de ma boutique ? Si la réponse est un éditeur d’app, tu as une dépendance de plus.

Et le jour où l’app est retirée de l’App Store, tes filtres partent avec elle.