Suivez votre progression
Accueil Trailhead
Accueil Trailhead

Découverte de la réutilisation du code et les contrôleurs Apex

Objectifs de formation

Une fois cette unité terminée, vous pourrez :
  • Expliquer la différence entre l’héritage et la composition pour la réutilisation de code.
  • Décrire les différences syntaxiques et architecturales entre les contrôleurs Apex des composants Aura et ceux de Visualforce.

Héritage ou composition

Il serait facile de passer une semaine sur cette question si nous étions dans un séminaire intensif de génie logiciel, mais nous tâcherons d’être brefs.

Les composants Aura peuvent hériter des composants parent, l’héritage étant la principale technique de conception de code réutilisable. Cependant :

préférez la composition à l’héritage.

Le « Framework des Composants Lightning » porte ce nom pour une bonne raison. La composition est LE modèle fondamental de réutilisation de votre code.

Il y a deux raisons pour lesquelles vous devez adopter ce mantra.

  1. Dans l’implémentation du framework, l’héritage a des inconvénients non négligeables en termes de performances. Les détails peuvent évoluer, mais vous constaterez qu’utiliser l’héritage consomme plus de mémoire et de processeur que vous ne pourriez l’imaginer.
  2. Dans les composants Aura, l’héritage ne fonctionne pas exactement comme dans le langage Apex ou Java. C’est… problématique.

    À titre d’exemple, un composant enfant peut s’étendre à partir d’un composant parent. Il a par exemple accès aux gestionnaires d’actions et aux fonctions d’assistance du parent. Le composant enfant peut remplacer ces gestionnaires et ces fonctions par les siens. Cependant, le composant enfant ne peut pas étendre ces gestionnaires ou ces fonctions.

    La méthode d’assistance de votre composant enfant ne peut donc pas appeler super.uneFonctiondAide() dans son implémentation de uneFonctiondAide(), puis ajouter de la logique supplémentaire. Vous pouvez soit utiliser la fonction du parent telle qu’elle a été implémentée, soit la remplacer intégralement. Cette contrainte limite la réutilisation. Il existe une approche alternative qui utilise <aura:method>, au prix de quelques contorsions. C’est une approche puissante et prise en charge, mais si votre cas est simple, elle semblera un peu lourde.

Comme nous l’avons dit, l’héritage tel qu’il est implémenté dans les composants Aura est problématique. Et son implémentation peut fluctuer. Évitez les hiérarchies d’héritage complexes afin de pouvoir vous adapter quand le framework change.

Les contrôleurs Apex

Regardons un contrôleur côté serveur très simple pour aborder quelques points.
public with sharing class SimpleServerSideController {

    @AuraEnabled
    public static String serverEcho(String echoString) {
        return ('Hello from the server, ' + echoString);
    }
}

Il y a plusieurs points notables, dont des différences précises par rapport à un contrôleur Visualforce.

  • Le point le plus évident est la nouvelle annotation @AuraEnabled. Si vous avez déjà utilisé JavaScript Remoting dans Visualforce, il est très proche de l’annotation @RemoteAction utilisée dans ces méthodes.
  • Les similarités avec JavaScript Remoting se poursuivent avec la signature de la méthode. Les méthodes de contrôleur côté serveur des composants Aura doivent être static, et public ou global.
  • Et comme les méthodes des contrôleurs côté serveur doivent être static, vous ne pouvez pas stocker d’état de composant côté serveur. Conservez l’état d’un composant dans ses attributs côté client, comme expliqué dans la section précédente.
  • Les actions côté serveur retournent des données. Elles ne peuvent pas retourner de PageReference. Implémentez votre logique de navigation côté client, pas côté serveur.
  • Toboggan ! Un point qui n’est peut-être pas évident, mais qui vous causera beaucoup de migraines si vous n’y prêtez pas attention, c’est que les noms de paramètres utilisés dans la déclaration de méthode Apex doivent correspondre aux noms de paramètres que vous utilisez lorsque vous créez les actions côté client.
  • Toboggan ! Une autre contrainte pas évidente : ne donnez pas le même nom à une méthode de contrôleur côté serveur et à une fonction gestionnaire d’action côté client. Les choses risqueraient d’être… bizarres. Vous devez choisir une convention de nommage pour vos méthodes côté client et côté serveur afin que la distinction soit claire et les confusions impossibles.

Revenons sur les deux derniers points. Les noms de paramètres doivent correspondre lorsqu’ils sont transmis entre code côté client et côté serveur. Les noms des méthodes ne doivent pas être les mêmes.

Composants Aura ou Apex

Pour tout composant Aura utilisant Apex côté serveur, vous transmettez des données entre le code JavaScript du composant Aura et le code Apex côté serveur. La majeure partie des paramètres et des résultats sont convertis automatiquement d’un format de données à l’autre. Il existe cependant quelques limites qui peuvent affecter la conception de votre logiciel.

Apex n’est pas JavaScript

Toboggan ! Cela peut paraître évident, mais il n’est pas inutile de rappeler que quand vous transmettez des objets entre le côté client et le côté serveur, et inversement, ils subissent des transformations. Un objet Apex, qui peut contenir des propriétés reposant sur une logique complexe, devient un simple objet JavaScript uniquement composé de paires nom:valeur lorsqu’il est envoyé comme réponse. Les variables d’instance publiques sont transmises, et les méthodes publiques de récupération de l’objet Apex sont appelées et résolues vers des valeurs statiques au moment où l’objet est sérialisé et retourné. Et ainsi de suite.

Échelle ! Bien que le processus soit de type déterministe et compréhensible, il est parfois plus pratique de créer des classes spéciales simplifiées en Apex uniquement pour préparer et renvoyer les données vers les composants Aura. Utilisez ces classes plutôt que vos classes de traitement pour transférer les données.

Cela semble représenter plus de travail (de code), et c’est le cas. Cependant, cela permet aussi de supprimer une partie de la complexité et de l’opacité du processus de transformation-sérialisation-transmission-désérialisation qui a lieu lorsque les données sont retournées d’Apex vers JavaScript. Supprimer cette complexité peut simplifier le débogage.

sObject

Vous pouvez créer de nouveaux sObjects en JavaScript, y compris des objets personnalisés. Il y a un peu syntaxe complémentaire, mais elle est claire. Ces sObjects peuvent être envoyés comme paramètres vers des requêtes vers l’Apex côté serveur. Vous pouvez retourner des sObjects en réponse depuis Apex, et le framework s’occupe de la transformation.

Classes personnalisées

Échelle ! Il n’est pas possible de passer efficacement une classe Apex personnalisée en tant que paramètre du JavaScript côté client vers l’Apex côté serveur. Utilisez plutôt un objet JavaScript simple pour encapsuler les données structurées du paramètre. Analysez l’objet dans votre code Apex, par exemple dans la classe constructeur de votre classe Apex.

Vous pouvez retourner une classe Apex personnalisée dans la réponse de votre contrôleur côté serveur au JavaScript côté client. Cependant, il sera sérialisé et désérialisé dans ce processus, et le résultat ne sera peut-être pas exactement ce que vous attendez. Échelle ! Il vaut souvient mieux retourner une map avec les éléments de données que vous souhaitez inclure, ou un JSON que vous aurez construit vous-même.

Classes internes

Toboggan ! Vous ne pouvez pas utiliser de classes internes Apex dans du code de composants Aura. Votre code Apex côté serveur peut les utiliser pour traiter une requête, mais la réponse retournée au client ne peut pas être une instance d’une classe interne.

Héritage

Toboggan ! Vous ne pouvez pas utiliser l’héritage avec les classes Apex personnalisées que vous souhaitez renvoyer en réponse à des composants Aura.

Traiter les erreurs côté serveur

Échelle ! Si votre code Apex rencontre des erreurs, vous pouvez créer et lancer une AuraHandledException. Attraper d’autres exceptions, telles qu’une exception DML, et les relancer sous forme de AuraHandledException crée également une bien meilleure expérience côté client.