La réponse courte

La question « Flow ou Apex » reçoit une réponse incorrecte lorsqu'elle est examinée sous l'angle de la facilité d'écriture ou de la disponibilité des développeurs. La bonne réponse dépend de quatre facteurs techniques : le nombre d'enregistrements traités par transaction, la nécessité d'une atomicité complète de la logique, la complexité des conditions et des branches, et l'équipe qui assurera la maintenance du composant dans un an. Flow est la valeur par défaut pour la plupart des automatisations métier, mais il existe des points de bascule clairs où la poursuite avec Flow crée un risque opérationnel plutôt qu'un « code moins élégant ».

Cet article traite de la décision de sélection elle-même : comment identifier à l'avance si la logique justifie Apex, et comment éviter que le choix ne soit fait par défaut plutôt que par un jugement réfléchi. La question du nettoyage des Flows et des processus d'automatisation existants qui se sont accumulés en tant que dette technique est abordée dans un article séparé et ne fait pas partie de la discussion ici.

Ce qui les différencie concrètement au niveau de la plateforme

Flow est un moteur déclaratif qui est traduit en temps réel en instructions exécutant du DML et du SOQL au nom de l'utilisateur, tandis qu'Apex est un code compilé qui s'exécute sous les mêmes Governor Limits mais avec un contrôle direct de l'ordre des opérations. La première différence pratique est le Bulkification : un développeur Apex construit explicitement une boucle qui collecte tous les enregistrements dans un tableau et exécute un seul DML, tandis qu'avec Flow, il est facile de construire une boucle qui exécute une opération DML ou une requête à chaque itération séparément — un modèle qui atteint les 101 requêtes autorisées beaucoup plus rapidement.

La deuxième différence est le contrôle de la transaction. Apex permet les Savepoint et Database.rollback pour une annulation partielle, la gestion des DmlException au niveau de l'enregistrement individuel via Database.insert(list, false), et une logique conditionnelle complexe sans limite de profondeur de branche. Dans Flow, la gestion des erreurs est définie au niveau du Fault Path pour chaque élément, et cela fonctionne bien pour les scénarios linéaires mais devient difficile à suivre lorsqu'il y a plus de quelques chemins de défaillance parallèles.

Cadre de décision : quatre tests avant de choisir un outil

Test de volume

Règle générale : si le processus s'exécute sur un seul enregistrement suite à une action utilisateur (création d'un Lead, modification du statut d'une opportunité), Flow est presque toujours suffisant. Si le processus s'exécute sur des dizaines, voire des milliers d'enregistrements à la fois — mise à jour périodique, traitement d'un Batch provenant d'une intégration, nettoyage de données planifié — Apex avec Batchable ou Queueable est le choix sûr, car il offre un contrôle total sur le Bulkification et la gestion des Governor Limits face à un volume variable.

Test d'atomicité

Il faut se demander : si une partie de la mise à jour échoue, l'autre partie peut-elle être conservée ? Si la réponse est « non » — par exemple, la mise à jour d'une commande et la création d'un enregistrement de facturation qui doivent impérativement se produire ensemble — Apex avec Savepoint est la bonne approche pour garantir cela. Flow ne fournit pas de Rollback complet entre les éléments sans une construction manuelle et complexe de la logique de compensation.

Test de complexité des branches

Un Flow avec plus de 6 à 8 éléments de décision imbriqués devient difficile à lire et coûteux à tester, même si chaque branche individuelle est simple. Lorsque la complexité de la logique métier dépasse ce seuil, l'écriture de cette même logique sous forme de fonction Apex documentée avec des tests unitaires (@isTest) est généralement moins coûteuse à maintenir, même si le temps de développement initial est plus long.

Test de maintenance et de propriété

Il faut se demander qui maintiendra le composant dans un an, et non qui le construit actuellement. Si l'équipe d'Admin est celle qui devra fréquemment mettre à jour les règles métier — comme la modification des conditions de remise ou des seuils — Flow est préférable même si Apex est techniquement plus « propre », car il est accessible pour la mise à jour sans cycle de déploiement. Si les modifications nécessitent des connaissances du schéma de données et des tests de régression, Apex est le bon choix même s'il n'y a qu'une petite équipe de développement pour le maintenir.

Tableau de décision

CritèreChoisir FlowChoisir Apex
Volume d'enregistrements par transactionJusqu'à quelques dizainesCentaines à milliers
Exigence d'atomicité entre plusieurs objetsNon critiqueCritique — Rollback complet requis
Nombre de branches de décisionJusqu'à 6-8 environAu-delà, ou logique récursive
Fréquence de changement des règles métierFréquente, par l'AdminRare, nécessite des tests de régression
Nécessité d'appeler une API externe complexeAppel unique simple (HTTP Callout)Logique de Retry, Auth complexe ou Batch
Exigence de tests automatisés (CI)LimitéeComplète, @isTest avec Coverage
Intégration avec un Scheduled Job régulierNon directement adaptéNaturel via Schedulable

Exemple de scénario : une entreprise d'équipement médical avec un processus d'approbation de commandes

Une entreprise d'équipement médical de taille moyenne avec environ 40 représentants commerciaux a implémenté un Flow pour le processus d'approbation des commandes : vérification des stocks, calcul des remises, création d'un enregistrement d'approbation et envoi d'une alerte au responsable. Au début, cela fonctionnait bien pour une seule commande. Après six mois, un nouveau scénario a été ajouté — l'importation de commandes groupées à partir d'un fichier d'intégration avec l'ERP, créant entre 200 et 800 commandes simultanément.

Le Flow, déclenché via un Record-Triggered Flow au niveau « par enregistrement », exécutait une requête de vérification de stock de manière indépendante à chaque exécution. Avec l'importation de 500 commandes, le système a dépassé la limite de 100 requêtes dans une seule transaction et les commandes ont échoué sans message d'erreur clair pour l'utilisateur. L'équipe a identifié que le problème n'était pas le Flow lui-même mais l'adéquation entre un processus conçu pour un seul enregistrement et un scénario de volume qui n'existait pas au moment de la construction.

La solution n'a pas été de supprimer le Flow. L'équipe a divisé la logique : le Flow est resté responsable du processus manuel d'une seule commande (test de volume bas, besoin de mises à jour fréquentes des règles de remise par l'Admin), tandis que le processus d'importation groupée a été transféré à un Apex Batch Job qui effectue un Bulkification complet, vérifie le stock en une seule requête centralisée et exécute un seul DML pour tous les enregistrements. Les deux mécanismes appellent la même couche de logique métier partagée (une classe Apex que le Flow appelle également via Invocable Method), afin que la règle de remise ne soit pas maintenue deux fois.

Risques courants et mesures préventives

RisqueComment cela se manifeste concrètementMesure préventive
Flow sur un volume croissantUn processus a fonctionné pendant six mois puis a échoué silencieusement sur les Governor LimitsVérifier le volume prévu à l'avance et planifier un point de transfert vers Apex avant d'atteindre la limite
Duplication de la logique métier dans Flow et ApexDeux endroits calculent la remise différemmentCentraliser le calcul métier dans une couche Apex commune que les Flows appellent également
Ordre de déclenchement imprévuPlusieurs Flows et Triggers sur le même objet entrent en conflitUn seul Trigger Handler central en Apex pour chaque objet critique
Gestion partielle des erreurs dans un Flow complexeUne partie des enregistrements est mise à jour et une partie non, sans visibilitéTransférer les processus nécessitant l'atomicité vers Apex avec Savepoint
Apex sans tests suffisantsUn petit changement rompt un processus critique lors du prochain déploiementExiger un Coverage réel et non seulement un pourcentage formel, y compris les scénarios d'échec

Checklist de décision avant la construction

  • ☐ Le volume attendu sur un an, et non seulement la situation actuelle, a été vérifié.
  • ☐ Il a été défini si le processus exige l'atomicité entre plusieurs objets.
  • ☐ Les branches de décision prévues dans la logique ont été comptées.
  • ☐ L'équipe de maintenance du composant et la fréquence de modification des règles sont connues.
  • ☐ Il a été vérifié si une logique similaire existe déjà en Apex ou dans un autre Flow sur le même objet.
  • ☐ L'ordre des déclencheurs ("Trigger Order") a été défini s'il existe plusieurs mécanismes d'automatisation sur l'objet.
  • ☐ Si Apex est choisi — les scénarios de test, y compris l'échec partiel, ont été définis.
  • ☐ Si Flow est choisi — un Fault Path a été défini pour chaque élément critique.

Comment cela s'intègre à l'architecture globale

Le choix du bon outil pour une automatisation isolée n'est qu'une couche dans un tableau plus vaste de l'architecture CRM, où le modèle de données et les autorisations influencent ce que Flow ou Apex peuvent toucher. Lorsque l'automatisation franchit une frontière vers une organisation externe — par exemple, une vérification de stock en temps réel avec un ERP — le choix entre Flow et Apex s'intègre également dans les considérations des modèles d'intégration et de la manière dont Salesforce se connecte à un ERP en termes de latence et de gestion des pannes.

Dans les organisations qui exploitent plusieurs Org, il convient également de vérifier si la logique métier est identique dans toutes — un sujet abordé dans le guide Single Org vs Multi Org et qui influence la question de savoir s'il est judicieux de centraliser la logique dans un paquet Apex partagé.

Résumé

Le choix entre Flow et Apex n'est pas une question de compétence d'équipe ou de préférence personnelle, mais le résultat de quatre tests techniques : le volume, l'atomicité, la complexité des branches et la fréquence des changements. Flow est le choix par défaut approprié pour la plupart des automatisations qui concernent un seul enregistrement et changent fréquemment. Apex est requis lorsqu'il y a un volume significatif, lorsqu'un contrôle total de la transaction est nécessaire, ou lorsque la complexité logique dépasse le seuil qui peut encore être maintenu via une interface déclarative. Une organisation qui institutionnalise ces tests dans son processus de travail — plutôt que de les laisser à la discrétion ad hoc de chaque développeur — évite la plupart des cas où une automatisation qui fonctionnait bien au début se brise silencieusement lorsque le volume augmente.