Logomark

LARAVEL

Un framework qui rend heureux
Voir cette catégorie
Vers le bas
Complétion d'adresse
Dimanche 30 août 2026 15:16

Comme je suis en train de remanier mon projet « shop » de plateforme de commerce en ligne, je remets en cause pas mal d'éléments. Je me suis particulièrement attardé sur le formulaire de saisie des adresses de livraison et de facturation. En particulier, je me suis dit qu'il serait bien d'avoir une complétion automatique pour les adresses. J'ai donc exploré les packages existants, sans trop de succès. J'ai donc créé le mien, plutôt adapté à la France, mais couvrant les adresses du monde entier.

Les API disponibles

J'ai exploré les API existantes et voici mes trouvailles :

BAN

Pour les adresses en France (et outre-mer), il n'y a pas lieu de réfléchir, car le gouvernement nous propose une API gratuite. Elle est à la fois simple et efficace. On peut aussi faire de la géolocalisation, même inversée, mais ce n'est pas notre sujet. La limite d'utilisation est plutôt généreuse : 50 appels / seconde / IP.

Geoapify

Les adresses en France ayant trouvé leur solution officielle, il faut maintenant s'occuper des autres localisations. Il existe de nombreux services et, parmi toutes ces propositions, j'ai choisi Geoapify. Déjà, la quantité gratuite est généreuse (3 000 crédits par jour). Ensuite, c'est simple et rapide. Côté RGPD, on est tranquille avec des serveurs en Europe. Les tarifs sont plutôt intéressants. Vous pouvez trouver une bonne démonstration ici.

Autres possibilités

Il existe évidemment d'autres prestataires. Par exemple Mapbox qui propose 1000 sessions (lors d'une session on peut faire plusieurs recherches) gratuites par mois avec de bons SDKs JavaScript natifs. 

Une autre option intéressante est LlocationIQ. Le quota gratuit est de 5000 demandes par jour avec une limite de 2 demandes par seconde et 60 demandes par minute. Il y a une jolie démonstration ici.

Il est relativement facile de créer un nouveau provider dans le package pour un autre prestataire...

Le package

Installation

Le package est ici. Il est facile à installer :

composer require bestmomo/laravel-address-completion

On peut publier la configuration :

php artisan vendor:publish --tag="address-completion-config"

Mais pour une utilisation classique ce n'est pas nécessaire.

Pour l'API de Geoapify vous devez créer un compte sur leur site et vous récupérez ainsi une clé API que vous placez dans le fichier .env :

GEOAPIFY_KEY=votre_clé_ici

Vous disposez ainsi par défaut du quota gratuit et vous pouvez évidemment payer pour en avoir plus...

Utilisation

L'utilisation est simple parce que j'ai prévu une façade :

use AddressCompletion\Facades\Address;

$addresses = Address::search('10 rue de Paris');

foreach ($addresses as $address) {
    echo $address->label;
}

Vous pouvez préciser le pays avec son code ISO (la valeur par défaut est FR) :

$addresses = Address::search('10 Downing Street', 'UK');

Et vous pouvez aussi changer le nombre de réponses (la valeur par défaut est 5) :

$addresses = Address::search('10 Downing Street', 'UK', 8);

Les données retournées

Le package utillise un DTO (Data Transfer Object). C'est un patron de conception (design pattern) dont le rôle classique est de transporter des données d'un endroit à un autre dans une application, sans contenir aucune logique métier. On sait ainsi exactement quelles propriétés sont disponibles. Il est on ne peut plus simple :

<?php

namespace AddressCompletion\DTO;

final readonly class Address
{
    public function __construct(
        public string $label,
        public string $street,
        public string $postcode,
        public string $city,
    ) {}
}

Ainsi vous récupérez un tableaux d'objets avec ces propriétés immutables quelle que soit l'API utilisée (BAN ou Geoapify ou si on en ajoute une autre un jour) :

Propriété Description
label Adresse formattée
street Numéro et nom de la rue
postcode Code postal
city Ville ou localité

Vous n'avez plus qu'à les adapter en fonction de vos besoins.

Le cache

Les résultats sont mis en cache automatiquement pendant 5 minutes, ce qui fait gagner des crédits et du temps. On distingue par provider, par pays et par recherche.

Architecture

J'ai prévu une interface pour fixer la syntaxe quel que soit le provider utilisé :

<?php

namespace AddressCompletion\Contracts;

use AddressCompletion\DTO\Address;

interface AddressProvider
{
    /**
     * @return bool
     */
    public function supports(string $country): bool;

    /**
     * @return Address[]
     */
    public function autocomplete(string $query, ?string $country = null, ?int $limit = null): array;
}

Et une classe pour gérer les providers :

<?php

declare(strict_types=1);

namespace AddressCompletion;

use AddressCompletion\Contracts\AddressProvider;
use AddressCompletion\DTO\Address;

class AddressManager
{
    private readonly string $defaultCountry;

    /**
     * @param AddressProvider[] $providers
     */
    public function __construct(
        private readonly array $providers,
    ) {
        $this->defaultCountry = (string) config('address-completion.default_country');
    }

    /**
     * @return Address[]
     */
    public function search(string $query, ?string $country = null, ?int $limit = null): array
    {
        $country = strtoupper($country ?: $this->defaultCountry);

        foreach ($this->providers as $provider) {
            if ($provider->supports($country)) {
                return $provider->autocomplete($query, $country, $limit);
            }
        }

        return [];
    }
}

Si le pays est défini on l'utilise, sinon on prend celui par défaut. Ensuite on regarde si on peut utiliser l'api BAN (il est placé en tête dans la configuration), si ce n'est pas le cas on passe à Geoapify.

Conclusion

Je pense avoir créé un package simple et facile d'utilisation. On peut facilement ajouter des providers et des fonctionnalités supplémentaires.



Par bestmomo

Aucun commentaire