TD1: Interrogation d'API

Mise en place

Au cours de nos TDs, nous allons interroger et développer des API. Les exercices porteront sur un mini-projet de chat géolocalisé. Vous trouverez ici le dépôt original :

Auquel il faudra apporter des modifications.

Lisez les instructions pour mettre en place votre propre dépôt, et faites tourner l'application originale. L'application devrait ressembler à ceci :

Attention soyez organisé! Cette application sera réutilisée dans les TP suivants.

Ajoutez un message à l'emplacement de votre choix. Vous trouverez manuellement les coordonnées, par exemple à l'aide de Google Maps,

Ajout du champ adresse

Dans l'application actuelle, il est uniquement possible de déposer et de consulter les messages en précisant manuellement la longitude et la latitude. Cela permet de tester le code, mais c'est une façon très peu pratique de se localiser !

Lancez:

symfony console make:entity

Puis ajoutez un champ address de type text à l'entité Message. Lancez :

symfony console doctrine:schema:update --force

Pour mettre à jour votre base de données.

Modifiez ensuite le formulaire (MessageType.php et le template message/_form.html.twig) pour remplacer les coordonnées longitude/latitude par un champ adresse.

Enfin, modifiez la liste des messages pour y faire apparaître l'adresse.

À ce stade, on ne pourra pas encore ajouter de message, car la longitude et la latitude sont des champs requis, nous allons nous en occuper juste après!

API Adresses

Lancement de Postman

Nous proposons maintenant à l'utilisateur de saisir son adresse, mais nous avons besoin de connaître l'emplacement de cette adresse sur la carte pour pouvoir le situer.

Pour cela, il nous faut convertir l'adresse en coordonnées longitude/latitude. Nous allons donc interroger l'API suivante :

Nous allons tout d'abord tester l'API "à la main". Pour cela, nous allons utiliser Postman, un outil permettant de forger des requêtes HTTP :

Ce script téléchargera et lancera Postman sur votre poste. Au département, vous pourrez aussi lancer: /mnt/raddix/opt/postman/Postman

Au démarrage, ne créez pas de compte, cliquez sur "Skip and go to the app"

Interrogation manuelle d'API

À l'aide de Postman et du endpoint /search, testez la recherche de longitude/latitude à partir d'une adresse.

À l'aide du endpoint /search/csv, testez la résolution d'adresses par lot en CSV.

Résolution des adresses

Installation de Guzzle

Nous allons maintenant interroger l'API de manière à remplir automatiquement les données de l'application. Nous interrogerons l'API côté serveur (en PHP) au moment où un utilisateur fournira une adresse. Pour cela, nous allons utiliser une bibliothèque PHP permettant d'envoyer des requêtes HTTP (comme Postman), qui se nomme Guzzle:

symfony composer require guzzlehttp/guzzle:^7.0

Création d'un Service

Nous allons écrire du code PHP qui interrogera l'API distante. Nous allons placer ce code dans une classe AddressAPIService, dans src/Services:

<?php
// src/Service/AddressAPIService.php
namespace App\Services;

use GuzzleHttp\Client;

class AddressAPIService
{
    public const base_uri = 'https://api-adresse.data.gouv.fr/';
}

Pour accéder à cette classe, ajoutez simplement un argument de type AddressAPIService à l'action du contrôlleur qui en a besoin.

Obtention des longitude/latitude

Au moment où un message est posté, interrogez l'API des adresses à l'aide de Guzzle pour obtenir la longitude et la latitude (vous utiliserez le meilleur résultat d'après l'API).

Aidez-vous de la documentation officielle, et écrivez une fonction dans AddressAPIService, par exemple:

public function getLngLat(string $address): ?array

Qui prendra en paramètre une adresse et retournera la longitude/latitude, ou null si aucun résultat n'a été trouvé.

Modifiez ensuite le code du formulaire pour utiliser cette fonction.

ProTip: vous pouvez générer un morceau du code en utilisant le volet latéral "code snippet" de Postman.

Si il n'y a aucun résultat, vous afficherez un message d'erreur

Obtention des adresses

On souhaite maintenant obtenir les adresses correspondantes aux longitudes/latitudes déjà en base.

Pour ce faire, on utilisera le endpoint /reverse/csv, qui permet d'obtenir les adresses des coordonnées fournies par lot (on n'utilisera PAS /reverse).

Ajoutez une méthode à AddressAPIService:

public function getAddresses(array $lnglat): array

Qui prend en paramètre un tableau de longitude/latitude et retourne un tableau contenant les adresses trouvées. Ces adresses peuvent être null si aucune n'a été trouvé.

Vous ajouterez un bouton dans l'interface qui complétera les adresses inconnues.

Indication: vous aurez besoin de faire une requête POST multipart