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,
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!
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"
À 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.
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
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.
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
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