# Convertir une image via une route REST avant de la servir au front

> Faut-il vraiment livrer un JPEG lourd à un front headless qui sait très bien afficher du WebP ? Une route de conversion à la volée règle le problème côté serveur.

- Auteur : WordPress Développement
- Publié le : 2021-02-14
- Mis à jour le : 2021-02-14
- Catégorie : Headless &amp; API
- URL : https://www.wpmoderne.fr/headless/convertir-image-route-rest-avant-servir-front/

## L’essentiel

- WP_Image_Editor sait ouvrir, redimensionner et exporter une image
- Une route dédiée peut convertir un format à la demande
- Le résultat gagne à être mis en cache pour éviter de reconvertir à chaque appel

Un front headless doit-il vraiment recevoir la même image, dans le même format, quel que soit le navigateur qui la consommera ensuite ? La question mérite d'être posée dès qu'un projet découplé sert des images à plusieurs types de clients — une application mobile, un site web, un générateur de miniatures pour les réseaux sociaux — sans toujours pouvoir compter sur eux pour effectuer la conversion de format eux-mêmes.

## Le problème

La médiathèque de WordPress conserve les images dans leur format d'origine, généralement JPEG ou PNG selon ce que l'auteur a importé. L'API REST expose ce fichier tel quel via `source_url`, sans jamais reformater automatiquement le contenu pour le client qui le demande. Un front headless qui a besoin de WebP ou d'AVIF pour des raisons de poids doit donc soit convertir lui-même côté client (rarement possible), soit s'appuyer sur un service tiers de transformation d'image, soit demander au serveur WordPress de le faire à sa place, au moment de la requête.

## La recette : une route de conversion à la volée

> L'essentiel à retenir : WP_Image_Editor sait ouvrir, redimensionner et exporter une image ; Une route dédiée peut convertir un format à la demande ; Le résultat gagne à être mis en cache pour éviter de reconvertir à chaque appel

```
add_action( 'rest_api_init', function () {
    register_rest_route( 'medias/v1', '/convertir/(?P<id>\d+)', array(
        'methods'  => 'GET',
        'callback' => 'convertir_image_webp',
        'args'     => array(
            'id' => array( 'validate_callback' => 'is_numeric' ),
        ),
    ) );
} );

function convertir_image_webp( $request ) {
    $id     = (int) $request->get_param( 'id' );
    $chemin = get_attached_file( $id );

    if ( ! $chemin || ! file_exists( $chemin ) ) {
        return new WP_Error( 'image_introuvable', 'Aucune image pour cet identifiant.', array( 'status' => 404 ) );
    }

    $editeur = wp_get_image_editor( $chemin );
    if ( is_wp_error( $editeur ) ) {
        return $editeur;
    }

    $destination = wp_upload_dir()['path'] . '/' . $id . '.webp';
    $resultat    = $editeur->save( $destination, 'image/webp' );

    if ( is_wp_error( $resultat ) ) {
        return $resultat;
    }

    header( 'Content-Type: image/webp' );
    header( 'Cache-Control: public, max-age=31536000' );
    readfile( $resultat['path'] );
    exit;
}
```

La fonction `wp_get_image_editor()` retourne une instance de `WP_Image_Editor_GD` ou `WP_Image_Editor_Imagick` selon les extensions PHP disponibles sur le serveur. Sa méthode `save()` accepte un second argument précisant le type MIME cible, ce qui déclenche la conversion réelle du format sans que le développeur ait à manipuler directement la bibliothèque GD ou Imagick sous-jacente.

## Éviter de reconvertir à chaque appel

Sans précaution, cette route reconvertit l'image à chaque requête, ce qui gaspille du CPU pour un résultat identique à chaque fois. Une vérification simple de l'existence du fichier de destination avant de relancer la conversion règle l'essentiel du problème :

- Vérifier si le fichier `.webp` existe déjà dans le dossier de téléversement avant de reconvertir
- Ne régénérer le fichier que si l'image source a été modifiée depuis (comparaison de date de modification)
- Laisser un CDN ou un cache de reverse proxy absorber les requêtes suivantes grâce à l'en-tête `Cache-Control`

## Variantes utiles

La même route peut accepter un paramètre `largeur` pour redimensionner l'image avant conversion, via `$editeur->resize( $largeur, null, false )` appelé avant `save()`. Elle peut aussi accepter un paramètre `format` pour choisir entre WebP et AVIF selon ce que le client sait afficher, information généralement déduite de l'en-tête `Accept` envoyé par le navigateur plutôt que d'un paramètre explicite.

> Sur nos projets, cette route de conversion reste réservée aux images dont le format d'origine n'a pas pu être anticipé au moment de l'import ; pour tout le reste, générer directement les tailles au format WebP dès l'upload évite de faire porter ce coût de calcul à chaque requête front.

## En résumé

Convertir une image à la volée via une route REST personnalisée permet à un front headless de recevoir exactement le format qu'il sait afficher, sans dépendre d'un traitement côté client ni d'un service tiers. La méthode s'appuie entièrement sur l'API `WP_Image_Editor` déjà présente dans le cœur de WordPress, à condition de soigner la mise en cache du résultat pour ne pas transformer chaque affichage en nouvelle conversion.
