Fil d'Ariane
Drupal 10 : Conteneur de Services et Services
Comprendre le fonctionnement du conteneur de Service dans Drupal et la création de services.
Cet article a été initialement rédigé pour Drupal 8 mais son contenu est toujours d'actualité pour Drupal 9 et Drupal 10.
N'hésitez pas à nous contacter ou à vous inscrire à notre formation «Drupal pour les développeurs et développeuses» pour en savoir plus !
Les applications modernes s’appuyant sur la POO, beaucoup d’objets sont impliqués dans le cycle de vie d’une page. Afin de vous épargner la création, la réutilisation et la suppression de chacun de ces nombreux objets, depuis Drupal 8, Drupal s’appuie sur un objet spécial de Symfony appelé Service Container qui vise à vous simplifier la manipulation de ces dits objets.
Comme son nom l’indique, le Conteneur de Services gère des Services.
Un Service représente une fonctionnalité réutilisable à travers votre site (accès à la base de données, envoi d’un mail, traduction une chaîne, etc).
Si l’on prend l’exemple de la base de données, imaginez que vous ayez à configurer le nom d’utilisateur, le mot de passe et le nom de la base. Que vous soyez dans un environnement de production ou de développement, vous n’aurez probablement pas les mêmes valeurs. Si vous deviez saisir les nouvelles informations de connexion il vous faudrait passer par une recherche et remplacement de ces données à travers votre base de code. Cette action étant plutôt laborieuse, les Services permettent de simplifier cette gestion. En ayant une définition centralisée et découplée, il devient plus facile de les réutiliser, de les étendre ou de les remplacer.
Exemple de l’utilisation d’une classe pour encoder quelque chose en JSON :
# Controller.php
use Drupal\Component\Serialization\Json;
$json_serializer = new Json();
$json_serializer->encode(...);
Conversion en Service :
# core.services.yml
services:
serialization.json:
class: Drupal\Component\Serialization\Json
Exemple d’utilisation du Service :
# Controller.php
$service = \Drupal::service('serialization.json');
$service->encode(...);
C’est seulement lorsque l’appel au Service est fait que l’objet est créé et retourné, pas avant qu’il ne soit nécessaire. Cette instanciation tardive augmente les performances de l’application (pas de gaspillage) et surtout permet de facilement remplacer l’implémentation d’un Service, principe très important pour réaliser des tests unitaires.
Dans le quotidien de vos projets vous serez amenés à créer peu de nouveaux Services, mais il est fort à parier que vous aurez à modifier des Services existants pour surcharger des comportements, simuler la génération de données (pour les tests notamment).
Pour cela, il vous suffit d’implémenter une classe qui étend ServiceProviderBase
et qui possède une méthode alter()
dans laquelle sera décrite la surcharge.
# src/MyModuleServiceProvider.php
namespace Drupal\my_module;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderBase;
class MyModuleServiceProvider extends ServiceProviderBase {
/**
* {@inheritdoc}
*/
public function alter(ContainerBuilder $container) {
// Remplace la classe qui implémente le service "language_manager".
$definition = $container->getDefinition('language_manager');
$definition->setClass('Drupal\language_test\LanguageTestManager');
}
}
Certains des Services que vous implémenterez auront besoin d’arguments pour fonctionner. Ces arguments peuvent être des paramètres. Un paramètre est une donnée variable qui peut être définie dans un fichier centralisé. Les paramètres utilisés par un Service sont entourés du symbole %
pour indiquer qu’il s’agit de paramètres.
Exemple :
# module.services.yml
services:
twig:
class: Drupal\Core\Template\TwigEnvironment
arguments: ['@app.root', '@cache.default', '%twig_extension_hash%', '@twig.loader', '%twig.config%']
Les paramètres peuvent être définis directement dans le fichier de déclaration des services ou dans un autre fichier. Notez que si votre chaîne contient un @
, il faut l’échapper en doublant l’arobase. Dans l’exemple ci-dessus vous voyez le paramètre %twig.config%
dont la valeur par défaut est définie dans le fichier core.services.yml
mais que vous pouvez surcharger dans votre fichier services.yml
(dans sites/default
).
Découvrez maintenant comment appeler et injecter les dépendances de vos plugins, services ou hooks.
Commentaires
Votre commentaire
À propos de Julien
Co-fondateur - Scrum master & Expert technique
Utilisateur de Drupal depuis 2008, j’ai fait mes armes comme développeur chez Commerce Guys puis me suis mis à encadrer les nouveaux arrivants avant de donner des formations, participer aux avant ventes et accompagner les équipes au passage à Scrum.
Je suis impliqué dans la communauté française de Drupal depuis 2009, j’ai été tour à tour président puis vice-président de l’association Drupal France et francophonie entre 2011 et 2013.
Merci pour ton message.
Avec quel type d'objet fais tu ta requête au webservice ?
Si c'est un objet qui implément l'interface ResponseInterface, tu devrais pouvoir récupérer le code de réponse par $response->getStatusCode(). Attention cependant, certaines API sont mal développées et répondent un code 200 au lieu d'un code 400 en cas d'erreur et c'est dans le contenu de la réponse que se trouve le code d'erreur.
Concernant la question sur la séparation, il suffit de déclarer ta classe qui appelle ton API en tant que service et tu pourras t'en servir dans ton contrôleur. Regarde un œil à https://happyculture.coop/blog/drupal-8-injection-dependance aussi ça t'aidera peut être.
Merci pour votre réponse rapide. Voici mon code ci-dessous. Je suis encore débutant en drupal 8, donc si vous pouvez me citer quelques type d'objets pour faire la requête au web service ?!! Ou et comment je peux traiter la réponse de la requête ?
Résultat
Salut,
Ta question est super spécifique et demanderait une discussion pour comprendre le fond de ton problème. De fait, je doute que les commentaires de notre blog soient le lieu le plus approprié pour ça. Je te conseille donc de rejoindre la communauté sur Slack où tu trouveras plein de gens qui pourront tenter de t'aider.
Pour y parvenir, il faut suivre les instructions disponibles sur le site de Drupal : https://drupal.org/slack puis rejoindre le salon #drupal-france
À bientôt !