Different to use WP REST API vs Must-Use Plugin (MU Plugin)

Both approaches for handling AJAX requests in WordPress, using the WP REST API and using a Must-Use Plugin (MU Plugin), have their advantages and differences. Here’s a detailed comparison between the two, along with examples and considerations for permission handling.

WP REST API

The WP REST API is a modern and standardized way to handle AJAX requests. It allows you to create custom endpoints and leverage HTTP methods (GET, POST, etc.) and provides built-in support for authentication and permissions.

Example using WP REST API

// Register the custom REST API endpoint
add_action('rest_api_init', function () {
    register_rest_route('ss/v1', '/catalogs/update_total', array(
        'methods' => 'GET,POST',
        'callback' => array($this, 'update_total'),
        'permission_callback' => function () {
            return Ss_Utils::check_user_role(['administrator', 'editor']);
        }
    ));
});

// Your callback function for the endpoint
public function update_total(WP_REST_Request $request) {
    // Your update_total logic here
    return new WP_REST_Response(['success' => true, 'message' => 'Total updated'], 200);
}

// Utility function to check user role
class Ss_Utils {
    public static function check_user_role($roles) {
        $user = wp_get_current_user();
        foreach ($roles as $role) {
            if (in_array($role, (array) $user->roles)) {
                return true;
            }
        }
        return false;
    }
}

Must-Use Plugin (MU Plugin)

Must-Use Plugins are automatically activated and cannot be deactivated via the admin interface. They can be used to handle AJAX requests directly, bypassing the WordPress admin-ajax.php endpoint, which can result in performance improvements. However, this approach is less standardized than the WP REST API.

Example using MU Plugin

  1. Create the MU Plugin

    // wp-content/mu-plugins/ajax-handler.php
    
    <?php
    /*
     * Plugin Name: AJAX Handler
     * Description: Handles AJAX requests for the site.
     * Author: Your Name
     * Version: 1.0
     */
    
    if (!defined('DOING_AJAX')) {
        define('DOING_AJAX', true);
    }
    
    if (!defined('ABSPATH')) {
        require_once(dirname(__FILE__) . '/../../wp-load.php');
    }
    
    // Check if this is an AJAX request
    if (!empty($_REQUEST['action']) && $_REQUEST['action'] === 'update_total') {
        if (check_user_role(['administrator', 'editor'])) {
            update_total();
        } else {
            wp_send_json_error('Permission denied');
        }
    }
    
    function update_total() {
        // Your update_total logic here
        wp_send_json_success(['message' => 'Total updated']);
    }
    
    function check_user_role($roles) {
        $user = wp_get_current_user();
        foreach ($roles as $role) {
            if (in_array($role, (array) $user->roles)) {
                return true;
            }
        }
        return false;
    }
    
    function wp_send_json_success($data = null) {
        wp_send_json(array('success' => true, 'data' => $data));
    }
    
    function wp_send_json_error($data = null) {
        wp_send_json(array('success' => false, 'data' => $data));
    }
    
    function wp_send_json($response) {
        @header('Content-Type: application/json; charset=' . get_option('blog_charset'));
        echo json_encode($response);
        if (defined('DOING_AJAX') && DOING_AJAX) {
            wp_die();
        } else {
            die();
        }
    }
    
  2. Enqueue Scripts and Localize

    // Enqueue script in your theme's functions.php or a plugin file
    
    function enqueue_my_custom_ajax_script() {
        wp_enqueue_script('my-custom-ajax-script', get_template_directory_uri() . '/js/custom-ajax.js', array('jquery'), null, true);
    
        // Localize script to pass AJAX URL and nonce
        wp_localize_script('my-custom-ajax-script', 'MyCustomAjax', array(
            'ajax_url' => site_url('/wp-content/mu-plugins/ajax-handler.php'),
            'nonce'    => wp_create_nonce('my_custom_nonce'),
        ));
    }
    add_action('wp_enqueue_scripts', 'enqueue_my_custom_ajax_script');
    
  3. JavaScript File

    // js/custom-ajax.js
    
    jQuery(document).ready(function ($) {
        $('#my-button').click(function () {
            $.ajax({
                url: MyCustomAjax.ajax_url,
                type: 'POST',
                data: {
                    action: 'update_total',
                    security: MyCustomAjax.nonce,
                },
                success: function (response) {
                    if (response.success) {
                        alert(response.data.message);
                    } else {
                        alert('AJAX request failed: ' + response.data);
                    }
                },
                error: function (xhr, status, error) {
                    console.log('AJAX error: ' + error);
                }
            });
        });
    });
    

Comparison

Feature WP REST API MU Plugin
Standardization Highly standardized Less standardized
Activation Requires plugin activation Always active, cannot be deactivated
Permission Handling Built-in support Custom implementation
Performance May be slower due to overhead Potentially faster
Flexibility Highly flexible Flexible but requires custom code
Ease of Use Easier to use and maintain Requires more custom handling
Debugging Easier with built-in WP tools May require custom debugging tools
Security Uses WP’s built-in security features Requires custom security checks

Summary

  1. WP REST API:

    • Pros: Standardized, built-in permission handling, easier to maintain.
    • Cons: May have performance overhead, requires plugin activation.
  2. MU Plugin:

    • Pros: Always active, potentially faster, customizable.
    • Cons: Less standardized, requires custom permission handling, harder to maintain.

For most use cases, the WP REST API is recommended due to its ease of use, built-in features, and standardization. However, for critical performance-sensitive tasks that need to be always active, an MU Plugin can be a viable option. Ensure you implement proper permission checks and handle security concerns adequately.

Tags: