change de nom...
Dans cet article, nous plongeons dans la présentation de Nicolas Grekas, figure emblématique de la communauté Symfony. Sa conférence aborde une problématique fondamentale : bien que la communication serveur à serveur via HTTP paraisse simple en théorie, elle engendre souvent des défis inattendus en pratique. Cela renforce l'importance d'une intégration efficace des produits clients ou des SDK dans d'autres solutions finales, tout en nécessitant une capacité d'adaptation aux changements sans compromettre l'ensemble.
Nicolas nous guide à travers les complexités de l'écosystème des PSR en PHP, en partant de la compréhension fondamentale du composant Http Client jusqu'à la cartographie des requêtes dans notre domaine d'activité. Un accent particulier est mis sur l'importance d'offrir une expérience développeur de premier ordre lors de la création d'un SDK.
La présentation met en lumière l'utilisation efficace d'outils essentiels tels que php-http/discovery et symfony/http-client, tout en explorant les abstractions mises en œuvre par le composant HTTP Client. Nous avons soigneusement noté les éléments clés de cette présentation, que nous développerons dans cet article en fonction de notre perspective.
Le composant Symfony HttpClient se distingue par sa conception "standalone", conçu pour simplifier la gestion des requêtes HTTP dans les applications Symfony. Il s'intègre naturellement au framework et propose une interface stateless intuitive. Ce client HTTP est performant, supportant HTTP2 grace au curl gère les requêtes asynchrones avec streaming, offre un mécanisme de cache et capture les exceptions, permet de garder une connexion TCP ouverte entre les requêtes, permettant une expérience fluide et sans contraintes.
Voici un exemple de code utilisant Symfony HttpClient pour envoyer une requête GET vers l’API de GitHub. Ce composant gère la réponse de façon asynchrone, garantissant des performances optimales :
use Symfony\Contracts\HttpClient\HttpClientInterface;
class SymfonyDocs {
public function __construct( private HttpClientInterface $client, ) {}
public function fetchGitHubInformation(): array
{
// or through a factory method: HttpClient::create()->request(...)
$response = $this->client->request(
'GET',
'https://api.github.com/repos/symfony/symfony-docs'
);
return $response->toArray();
}
}
L'une des forces majeures de Symfony HttpClient réside dans sa compatibilité étendue avec plusieurs standards d'abstraction en PHP. Cette interopérabilité maximale se manifeste à travers la prise en charge des spécifications Symfony Client Contracts, PSR-18, HTTPlug (v1/v2), et les flux PHP natifs, assurant ainsi une compatibilité transparente avec divers abstractions et facilitant l'intégration harmonieuse avec d'autres bibliothèques.
Dans le fichier composer.json du package Symfony HttpClient, se trouve la section "provide" des packages virtuels, expliquant certains points importants :
Nicolas a évoqué le principe de Coding Against Abstractions dans ses explications, soulignant comment php-http/discovery favorise une architecture moderne, flexible et découplée, en accord avec les principes SOLID et les pratiques de développement modernes. Grâce aux packages virtuels mentionnés ci-dessus, php-http/discovery peut sélectionner automatiquement l’implémentation du client et de l'abstraction appropriée au projet, renforçant ainsi l'interopérabilité et permettant une intégration fluide sans configuration manuelle, tout en facilitant la coexistence avec d'autres bibliothèques PHP.
Pour en savoir plus sur l'utilisation de Discovery, vous pouvez consulter la documentation officielle ici.
HttpClient présente plusieurs avantages significatifs :
# config/packages/framework.yaml
framework:
http_client:
scoped_clients:
vemo.client:
base_uri: 'https://api.vemo.com'
headers:
Accept: 'application/json'
Authorization: 'Bearer %env(VEMO_API_TOKEN)%'
De plus le HttpClient propose quelques fonctionnalités supplémentaires :
$client = HttpClient::create(['max_host_connections' => 4]);
Symfony HttpClient facilite les tests grâce à la classe MockHttpClient, qui simule des requêtes HTTP. Elle utilise MockResponse pour représenter des réponses simulées, et JsonMockResponse pour des réponses JSON. Les réponses peuvent être définies statiquement ou générées dynamiquement via des callbacks. Par exemple, on peut initialiser MockHttpClient avec une liste de réponses ou utiliser MockResponse::fromFile() pour charger des données de test à partir de fichiers. Ces outils permettent de garantir le bon fonctionnement de votre logique métier sans dépendre d'API externes.
use Symfony\Component\HttpClient\Response\MockResponse;
use Symfony\Component\HttpClient\HttpClient;
$mockResponses = [
new MockResponse('{"key": "value"}', ['http_code' => 200]),
new MockResponse('{"error": "Not found"}', ['http_code' => 404]),
];
$client = HttpClient::create(['mock_response' => $mockResponses]);
$response = $client->request('GET', 'https://api.example.com/data');
Lors de la conférence API Platform, on a présenté une autre solution pour tester les API externes : PHP-VCR. Pour en savoir plus, c'est par ici : Comment tester une API externe en ayant 0 mocks ? |
Le composant Symfony HttpClient inclut un décorateur ThrottlingHttpClient qui permet de limiter le nombre de requêtes dans une période donnée, respectant ainsi les politiques de limitation de débit. Cela permet de gérer efficacement le flux des requêtes tout en évitant de surcharger les services externes.
use Symfony\Component\HttpClient\ThrottlingHttpClient;
$client = new ThrottlingHttpClient(HttpClient::create(), 2); // Limite à 2 requêtes par seconde
$response = $client->request('GET', 'https://api.example.com/data');
À partir de Symfony 6.1, il est désormais possible de configurer la logique d'autowiring à l'aide de l'attribut #[Autowire], offrant ainsi une approche plus flexible pour l'injection de dépendances.
use Symfony\Component\DependencyInjection\Attribute\Autowire;
class MyService
{
public function __construct(
#[Autowire('@service_id')] private $myService
) {
// $myService sera automatiquement mappé au service service_id
}
}
Dans la version de Symfony 7.1, #[AutowireInline], a été introduit pour permettre de définir l'ensemble de la configuration d'un service, y compris ses arguments, simplement en utilisant les paramètres du constructeur.
class SomeClass1
{
public function __construct(
#[AutowireInline(class: SomeSourceAwareLogger::class, args: [new Reference(LoggerInterface::class), 'bar'])]
public SomeSourceAwareLogger $someSourceAwareLogger,
) {
}
}
Enfin, si vous souhaitez explorer un peu plus l'histoire des attributs, n'hésitez pas à jeter un œil au retour de Clément Talleau sur sa conférence intitulée "API Platform, des développeurs d'attributs" |
En résumé, HTTPClient est un véritable atout dans notre boîte à outils de développeurs. Il nous permet de créer du code facilement interchangeable tout en offrant une meilleure flexibilité. Grâce aux conseils de Nicolas, qui nous encourage à éviter les implémentations spécifiques et à tirer parti de la discovery, notre expérience de développement s'en trouve améliorée. Avec ses fonctionnalités avancées et sa simplicité d'utilisation, HTTPClient s'impose comme le choix idéal pour nos projets, surtout dans le monde dynamique du développement web moderne, où la performance et la gestion des ressources sont essentielles. |