# Deux routes REST différentes pour un même contenu selon le rôle appelant

> Comment exposer plus ou moins de champs d'un même contenu selon qui interroge l'API, entre une seule route conditionnelle et deux routes distinctes.

- Auteur : Clément Hadrot
- Publié le : 2026-05-29
- Mis à jour le : 2026-05-29
- Catégorie : Headless &amp; API
- URL : https://wpmoderne.dev.wordpress-developpement.fr/headless/deux-routes-rest-meme-contenu-selon-role/

## L’essentiel

- Une seule route avec champs conditionnels, ou deux routes séparées
- Le contexte de requête REST distingue view et edit
- Deux routes distinctes clarifient l'intention

Faut-il exposer le même contenu à travers une seule route qui adapte ses champs selon les droits de l'appelant, ou vaut-il mieux créer deux routes distinctes, l'une publique et limitée, l'autre réservée et complète ? Cette question se pose dès qu'un contenu WordPress doit afficher davantage d'informations à un utilisateur authentifié qu'à un visiteur anonyme — un cas fréquent pour une fiche produit qui montrerait, par exemple, la marge ou le fournisseur uniquement à un acheteur professionnel connecté.

## Ce que WordPress prévoit déjà nativement : les contextes

L'API REST du cœur de WordPress distingue depuis toujours deux contextes de lecture, `view` et `edit`, déclarés dans le schéma de chaque champ. Un champ marqué uniquement pour le contexte `edit` n'apparaît dans la réponse que si la requête précise explicitement ce contexte, généralement réservé aux utilisateurs disposant des droits d'édition sur le contenu.

```
register_rest_field( 'produit', 'marge_beneficiaire', array(
    'get_callback' => function( $post ) {
        return get_post_meta( $post['id'], '_marge', true );
    },
    'schema' => array(
        'type'    => 'number',
        'context' => array( 'edit' ),
    ),
) );
```

Ce champ reste totalement absent d'une requête `GET /wp/v2/produit/42` classique, mais apparaît dans `GET /wp/v2/produit/42?context=edit`, appelée uniquement par un utilisateur autorisé.

## La limite de cette approche par contexte

Le mécanisme de contexte fonctionne bien pour ajouter des champs à une route déjà existante, mais il reste implicite : un développeur qui découvre la route pour la première fois ne devine pas immédiatement qu'un paramètre `context` change radicalement le contenu de la réponse. Sur un projet avec de nombreux champs conditionnels, cette approche peut rendre le comportement de la route difficile à documenter clairement.

> L'essentiel à retenir : Une seule route avec champs conditionnels, ou deux routes séparées ; Le contexte de requête REST distingue view et edit ; Deux routes distinctes clarifient l'intention

## L'alternative : deux routes explicitement distinctes

Pour un besoin de séparation plus marqué, notamment lorsque les champs sensibles sont nombreux ou que la logique d'autorisation dépasse un simple `context`, deux routes clairement nommées rendent l'intention plus lisible :

```
add_action( 'rest_api_init', function() {
    register_rest_route( 'catalogue/v1', '/produit/(?P<id>\d+)/public', array(
        'methods'             => 'GET',
        'callback'            => 'catalogue_produit_public',
        'permission_callback' => '__return_true',
    ) );

    register_rest_route( 'catalogue/v1', '/produit/(?P<id>\d+)/professionnel', array(
        'methods'             => 'GET',
        'callback'            => 'catalogue_produit_professionnel',
        'permission_callback' => function() {
            return current_user_can( 'read_private_produits' );
        },
    ) );
} );
```

Chaque route déclare son propre schéma de champs et son propre contrôle de permission, sans ambiguïté sur ce qu'elle expose. Le coût de cette clarté est une duplication partielle du code de récupération des données, généralement limitée en factorisant la logique commune dans une fonction interne partagée par les deux callbacks.

## Comment choisir entre les deux approches

- Un ou deux champs supplémentaires réservés aux utilisateurs autorisés : le mécanisme de `context` natif suffit largement, sans complexité ajoutée.
- Une différence structurelle importante entre les deux publics (des champs nombreux, une logique de permission distincte pour chacun) : deux routes séparées clarifient l'intention pour toute personne qui découvre l'API.
- Une équipe front qui consomme la route depuis plusieurs applications différentes, dont certaines ne doivent jamais recevoir les champs sensibles même par erreur : deux routes distinctes réduisent le risque d'une fuite accidentelle liée à un mauvais paramètre `context` oublié dans une requête.

## Un piège commun aux deux approches

Quelle que soit l'option retenue, le contrôle d'accès doit toujours être vérifié côté serveur, jamais seulement masqué côté front. Un champ absent d'une réponse REST parce que le front n'affiche pas cette information à l'écran ne protège rien si la route sous-jacente continue de le renvoyer à qui sait l'interroger directement. Le `permission_callback`, ou le contexte déclaré dans le schéma, reste la seule barrière réelle.

## Notre verdict

Pour la majorité des projets headless, le mécanisme de contexte natif de WordPress couvre le besoin sans complexité supplémentaire. Deux routes distinctes prennent tout leur sens à partir du moment où la différence entre les deux publics devient structurelle plutôt qu'anecdotique — un signe qu'il vaut mieux le nommer explicitement dans l'architecture de l'API plutôt que de le cacher derrière un simple paramètre de requête.
