26/03/2023

1. Requêtes HTTP

Lu 517 fois Licence Creative Commons

Installation

Pour réaliser cette fonctionnalité nous aurons besoin d'un client HTTP pour effectuer nos requêtes, et du serializer pour transformer les réponses de l'API en objets:

composer req http-client serializer

Nous utiliserons l'API Quotable. Les réponses prendront la forme suivante:

{
	"_id": "zJCNH3Q5shhD",
	"content": "Friends show their love in times of trouble, not in happiness.",
	"author": "Euripides",
	"tags": [
		"famous-quotes",
		"friendship"
	],
	"authorSlug": "euripides",
	"length": 62,
	"dateAdded": "2021-03-26",
	"dateModified": "2021-03-26"
}

DTO

Pour transformer les réponses JSON en objets, il faut créer un DTO que nous appelerons App\CitationDuJour\CitationResponse:

namespace App\CitationDuJour;

use Symfony\Component\Serializer\Annotation\SerializedName;

class CitationResponse
{
    #[SerializedName('content')]
    public string $citation;
    
    #[SerializedName('author')]
    public string $auteur;
}

L'attribut SerializedName indique le nom de la propriété dans le JSON. On souhaite que la clé content corresponde à la propriété $citation et que la clé author corresponde à $auteur.

Requête HTTP

Injecter le client HTTP et le serializer dans CitationService:

use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;

// ...
class CitationService
{
    public function __construct(
        private readonly HttpClientInterface $httpClient,
        private readonly SerializerInterface $serializer,
    ) {
    }

    // ...
}

Puis effectuer un appel à l'API dans une autre méthode avec la méthode request():

private function makeCitationRequest()
{
	$response = $this->httpClient->request(Request::METHOD_GET, 'https://api.quotable.io/random', [
		'query' => [
			'tags' => implode('|', [
				'wisdom',
				'motivational',
				'inspirational',
				'happiness',
				'friendship',
				'freedom',
			]),
		],
	]);
}

On passe la méthode HTTP, l'URL ainsi que des options comme ici des paramètres GET.
On obtient un objet Symfony\Contracts\HttpClient\ResponseInterface en retour qui fournit diverses informations sur la réponse HTTP dont le corps que l'on peut récupérer via getContent().

On souhaite transformer ce corps de réponse en JSON en une instance de notre DTO CitationResponse. La serialisation consiste à transformer un objet en un format de données (comme le JSON). Nous avons besoin d'effectuer l'opération inverse: déserialiser.

private function makeCitationRequest()
{
	// ...
	return $this->serializer->deserialize($response->getContent(), CitationResponse::class, 'json');
}

On peut alors utiliser cette méthode pour obtenir la citation et l'auteur:

public function getCitation(): string
{
	$citation = $this->makeCitationRequest();
	return $citation->citation;
}

public function getAuteurCitation(): string
{
	$citation = $this->makeCitationRequest();
	return $citation->auteur;
}

Les appels sont fonctionnels mais il y a tout de même un problème: la citation affichée n'a rien à voir avec l'auteur indiqué, et les deux changent à chaque changement de page. Voyons comment conserver la même citation pour la journée.