ITSkillsCenter
WordPress

Guide : WordPress REST API — introduction et utilisation

9 min de lecture

La REST API WordPress : ouvrir WordPress au monde

La REST API transforme WordPress d’un simple CMS en une plateforme de données accessible par n’importe quelle application. Votre contenu WordPress devient disponible en JSON via des URL standardisées : une application mobile, un site React, un dashboard personnalisé ou même un autre site peuvent lire et écrire dans votre WordPress sans toucher au PHP.

Comprendre les bases de la REST API

Qu’est-ce qu’une API REST ?

  • API : Interface de programmation — un contrat entre deux logiciels pour communiquer
  • REST : Un style d’architecture qui utilise les URLs et les méthodes HTTP (GET, POST, PUT, DELETE)
  • JSON : Le format de données échangé (léger et lisible)

L’URL de base

Votre API est accessible à :

https://votresite.com/wp-json/wp/v2/

Ouvrez cette URL dans votre navigateur — vous verrez la liste de tous les endpoints disponibles.

Les endpoints principaux

Lire du contenu (GET)

# Tous les articles publiés
GET /wp-json/wp/v2/posts

# Un article spécifique par ID
GET /wp-json/wp/v2/posts/123

# Les 5 derniers articles
GET /wp-json/wp/v2/posts?per_page=5

# Articles d'une catégorie spécifique (ID de la catégorie)
GET /wp-json/wp/v2/posts?categories=7

# Rechercher dans les articles
GET /wp-json/wp/v2/posts?search=wordpress

# Articles par auteur
GET /wp-json/wp/v2/posts?author=1

# Pagination
GET /wp-json/wp/v2/posts?page=2&per_page=10

# Toutes les pages
GET /wp-json/wp/v2/pages

# Toutes les catégories
GET /wp-json/wp/v2/categories

# Tous les tags
GET /wp-json/wp/v2/tags

# Les médias (images)
GET /wp-json/wp/v2/media

# Les utilisateurs
GET /wp-json/wp/v2/users

# Les commentaires
GET /wp-json/wp/v2/comments

Tester dans le navigateur

Vous pouvez tester directement dans la barre d’adresse de votre navigateur. Par exemple :

https://votresite.com/wp-json/wp/v2/posts?per_page=3&_fields=id,title,link

Le paramètre _fields limite les champs retournés — utile pour réduire la taille de la réponse.

Utiliser l’API avec JavaScript (fetch)

Lire les articles

// Récupérer les 6 derniers articles
async function getLatestPosts() {
    const response = await fetch('/wp-json/wp/v2/posts?per_page=6&_fields=id,title,excerpt,link,date,_embedded&_embed');
    const posts = await response.json();
    
    posts.forEach(post => {
        console.log(post.title.rendered);  // Titre
        console.log(post.excerpt.rendered); // Extrait HTML
        console.log(post.link);             // URL de l'article
        
        // Image mise en avant (avec _embed)
        if (post._embedded && post._embedded['wp:featuredmedia']) {
            console.log(post._embedded['wp:featuredmedia'][0].source_url);
        }
    });
    
    return posts;
}

Afficher les articles dans le HTML

async function displayPosts() {
    const response = await fetch('/wp-json/wp/v2/posts?per_page=6&_embed&_fields=id,title,excerpt,link,_embedded');
    const posts = await response.json();
    
    const grid = document.getElementById('posts-grid');
    
    posts.forEach(post => {
        const imageUrl = post._embedded?.['wp:featuredmedia']?.[0]?.source_url || '';
        
        grid.innerHTML += `
            <article class="post-card">
                ${imageUrl ? `<img src="${imageUrl}" alt="" loading="lazy">` : ''}
                <div class="post-card-content">
                    <h3><a href="${post.link}">${post.title.rendered}</a></h3>
                    ${post.excerpt.rendered}
                </div>
            </article>
        `;
    });
}

// Exécuter au chargement de la page
document.addEventListener('DOMContentLoaded', displayPosts);

Créer, modifier, supprimer du contenu

Les opérations d’écriture nécessitent une authentification.

Authentification par nonce (dans WordPress)

Si votre JavaScript s’exécute sur une page WordPress (thème ou plugin), utilisez le nonce :

// Côté PHP : rendre le nonce disponible
function montheme_api_scripts() {
    wp_enqueue_script('montheme-api', get_template_directory_uri() . '/js/api.js', array(), '1.0', true);
    wp_localize_script('montheme-api', 'wpApiSettings', array(
        'root'  => esc_url_raw(rest_url()),
        'nonce' => wp_create_nonce('wp_rest'),
    ));
}
add_action('wp_enqueue_scripts', 'montheme_api_scripts');
// Côté JavaScript : utiliser le nonce
async function createPost(title, content) {
    const response = await fetch(wpApiSettings.root + 'wp/v2/posts', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-WP-Nonce': wpApiSettings.nonce,
        },
        body: JSON.stringify({
            title: title,
            content: content,
            status: 'draft',  // 'publish' pour publier directement
        }),
    });
    
    const post = await response.json();
    console.log('Article créé :', post.id, post.title.rendered);
    return post;
}

// Modifier un article
async function updatePost(postId, data) {
    const response = await fetch(wpApiSettings.root + 'wp/v2/posts/' + postId, {
        method: 'POST',  // PUT fonctionne aussi
        headers: {
            'Content-Type': 'application/json',
            'X-WP-Nonce': wpApiSettings.nonce,
        },
        body: JSON.stringify(data),
    });
    return response.json();
}

// Supprimer un article (dans la corbeille)
async function deletePost(postId) {
    const response = await fetch(wpApiSettings.root + 'wp/v2/posts/' + postId, {
        method: 'DELETE',
        headers: {
            'X-WP-Nonce': wpApiSettings.nonce,
        },
    });
    return response.json();
}

Authentification par Application Password (externe)

Pour les applications externes (mobile, scripts serveur), utilisez les Application Passwords de WordPress :

  1. WordPress → Utilisateurs → votre profil → Application Passwords
  2. Entrez un nom (ex: « Mon App Mobile ») et cliquez « Add New Application Password »
  3. Copiez le mot de passe généré (il ne sera affiché qu’une fois)
# Utilisation avec curl
curl -X GET "https://votresite.com/wp-json/wp/v2/posts" \
  -u "admin:xxxx xxxx xxxx xxxx xxxx xxxx"

# Créer un article
curl -X POST "https://votresite.com/wp-json/wp/v2/posts" \
  -u "admin:xxxx xxxx xxxx xxxx xxxx xxxx" \
  -H "Content-Type: application/json" \
  -d '{"title":"Mon article via API","content":"Contenu ici","status":"draft"}'
// En JavaScript (avec Basic Auth encodé en Base64)
const credentials = btoa('admin:xxxx xxxx xxxx xxxx xxxx xxxx');

const response = await fetch('https://votresite.com/wp-json/wp/v2/posts', {
    headers: {
        'Authorization': 'Basic ' + credentials,
    },
});

Créer un endpoint personnalisé

Vous pouvez étendre l’API WordPress avec vos propres endpoints :

// Dans functions.php ou un plugin
function itsc_register_api_routes() {
    // GET /wp-json/itsc/v1/popular-posts
    register_rest_route('itsc/v1', '/popular-posts', array(
        'methods'  => 'GET',
        'callback' => 'itsc_get_popular_posts',
        'permission_callback' => '__return_true', // Public
        'args' => array(
            'count' => array(
                'default'           => 5,
                'sanitize_callback' => 'absint',
            ),
        ),
    ));
    
    // POST /wp-json/itsc/v1/contact
    register_rest_route('itsc/v1', '/contact', array(
        'methods'  => 'POST',
        'callback' => 'itsc_handle_contact',
        'permission_callback' => '__return_true',
        'args' => array(
            'name'    => array('required' => true, 'sanitize_callback' => 'sanitize_text_field'),
            'email'   => array('required' => true, 'sanitize_callback' => 'sanitize_email'),
            'message' => array('required' => true, 'sanitize_callback' => 'sanitize_textarea_field'),
        ),
    ));
}
add_action('rest_api_init', 'itsc_register_api_routes');

// Callback pour les articles populaires
function itsc_get_popular_posts($request) {
    $count = $request->get_param('count');
    
    $posts = get_posts(array(
        'post_type'      => 'post',
        'posts_per_page' => $count,
        'meta_key'       => 'post_views_count',
        'orderby'        => 'meta_value_num',
        'order'          => 'DESC',
    ));
    
    $data = array();
    foreach ($posts as $post) {
        $data[] = array(
            'id'    => $post->ID,
            'title' => $post->post_title,
            'link'  => get_permalink($post->ID),
            'views' => (int) get_post_meta($post->ID, 'post_views_count', true),
            'image' => get_the_post_thumbnail_url($post->ID, 'medium'),
        );
    }
    
    return new WP_REST_Response($data, 200);
}

// Callback pour le formulaire de contact
function itsc_handle_contact($request) {
    $name    = $request->get_param('name');
    $email   = $request->get_param('email');
    $message = $request->get_param('message');
    
    // Envoyer l'email
    $sent = wp_mail(
        get_option('admin_email'),
        'Nouveau message de ' . $name,
        "De : $name ($email)\n\n$message",
        array('Reply-To: ' . $email)
    );
    
    if ($sent) {
        return new WP_REST_Response(array('success' => true, 'message' => 'Message envoyé'), 200);
    }
    
    return new WP_Error('mail_failed', 'Erreur d\'envoi', array('status' => 500));
}

Cas d’usage concrets

1. Widget « Articles récents » en AJAX

Chargez les articles récents sans recharger la page :

<div id="recent-posts"></div>

<script>
fetch('/wp-json/wp/v2/posts?per_page=3&_fields=title,link,date')
    .then(r => r.json())
    .then(posts => {
        const html = posts.map(p => 
            `<a href="${p.link}">${p.title.rendered}</a>`
        ).join('');
        document.getElementById('recent-posts').innerHTML = html;
    });
</script>

2. Formulaire de contact sans plugin

<form id="contact-form">
    <input type="text" name="name" placeholder="Votre nom" required>
    <input type="email" name="email" placeholder="Votre email" required>
    <textarea name="message" placeholder="Votre message" required></textarea>
    <button type="submit">Envoyer</button>
    <div id="form-status"></div>
</form>

<script>
document.getElementById('contact-form').addEventListener('submit', async (e) => {
    e.preventDefault();
    const form = e.target;
    const status = document.getElementById('form-status');
    
    const data = {
        name: form.name.value,
        email: form.email.value,
        message: form.message.value,
    };
    
    status.textContent = 'Envoi en cours...';
    
    const response = await fetch('/wp-json/itsc/v1/contact', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data),
    });
    
    const result = await response.json();
    status.textContent = result.success ? 'Message envoyé !' : 'Erreur, réessayez.';
    if (result.success) form.reset();
});
</script>

3. Application mobile avec l’API WordPress

Votre contenu WordPress devient le backend d’une app mobile. Avec React Native ou Flutter :

// React Native - Exemple simplifié
const API_URL = 'https://votresite.com/wp-json/wp/v2';

async function fetchPosts() {
    const response = await fetch(`${API_URL}/posts?_embed&per_page=10`);
    return response.json();
}

async function fetchCategories() {
    const response = await fetch(`${API_URL}/categories`);
    return response.json();
}

C’est le concept du « Headless WordPress » : WordPress gère le contenu, une autre technologie gère l’affichage.

Sécuriser votre API

Restreindre les endpoints publics

Par défaut, l’API expose beaucoup d’informations. Limitez ce qui est visible :

// Masquer la liste des utilisateurs pour les non-connectés
function itsc_restrict_user_endpoint($response, $user, $request) {
    if (!current_user_can('list_users')) {
        return new WP_Error('rest_forbidden', 'Accès non autorisé', array('status' => 403));
    }
    return $response;
}
add_filter('rest_prepare_user', 'itsc_restrict_user_endpoint', 10, 3);

// Désactiver complètement l'endpoint utilisateurs
function itsc_remove_users_endpoint($endpoints) {
    if (isset($endpoints['/wp/v2/users'])) {
        unset($endpoints['/wp/v2/users']);
    }
    if (isset($endpoints['/wp/v2/users/(?P<id>[\d]+)'])) {
        unset($endpoints['/wp/v2/users/(?P[\d]+)']);
    }
    return $endpoints;
}
add_filter('rest_endpoints', 'itsc_remove_users_endpoint');

Rate limiting

Protégez votre API contre les abus. Cloudflare fait ça nativement, ou ajoutez un contrôle côté WordPress :

function itsc_rate_limit_api($result, $server, $request) {
    $ip = $_SERVER['REMOTE_ADDR'];
    $transient_key = 'api_rate_' . md5($ip);
    $count = (int) get_transient($transient_key);
    
    if ($count > 100) { // Max 100 requêtes par minute
        return new WP_Error('rate_limit', 'Trop de requêtes', array('status' => 429));
    }
    
    set_transient($transient_key, $count + 1, MINUTE_IN_SECONDS);
    return $result;
}
add_filter('rest_pre_dispatch', 'itsc_rate_limit_api', 10, 3);

Outils pour tester l’API

  • Navigateur : Pour les requêtes GET simples, collez l’URL dans la barre d’adresse
  • Postman : Application desktop pour tester toutes les méthodes (GET, POST, PUT, DELETE) avec authentification
  • curl : En ligne de commande, rapide pour les tests
  • Thunder Client : Extension VS Code, comme Postman mais intégré à votre éditeur
Besoin d'un site web ?

Confiez-nous la Création de Votre Site Web

Site vitrine, e-commerce ou application web — nous transformons votre vision en réalité digitale. Accompagnement personnalisé de A à Z.

À partir de 350.000 FCFA
Parlons de Votre Projet
Publicité