2026年5月22日

2026年5月22日

WordPress REST APIが動作しない問題を解決する方法

はじめに

WordPressのREST APIを使おうとすると{"code":"rest_no_route","message":"一致するルートが見つかりませんでした"}エラーが返る・/wp-json/wp/v2/postsにアクセスすると403 Forbiddenになる・カスタム投稿タイプがREST APIのエンドポイントに出てこない・JWT認証プラグインを使っているがトークンを渡しても401 Unauthorizedが返るといった問題は、パーマリンク設定・show_in_restフラグ・REST API無効化プラグイン・認証ヘッダーの設定が原因です。

症状・原因

  • パーマリンクが「基本」設定のためREST APIのURLが解決できない
  • セキュリティプラグインやWAFがREST APIへのアクセスをブロックしている
  • カスタム投稿タイプのregister_post_type()show_in_restfalseにしている
  • Apache/NginxがAuthorizationヘッダーをPHPに渡していない

解決手順

ステップ1:REST APIの動作を診断する

# REST APIの基本動作確認
curl -s https://example.com/wp-json/ | python -m json.tool | head -20

# 投稿一覧の取得テスト
curl -s https://example.com/wp-json/wp/v2/posts?per_page=1

# 認証付きリクエスト(Application Passwordsを使用)
curl -s -u "username:application_password" \
    https://example.com/wp-json/wp/v2/users/me

# wp-cli でREST APIルート一覧を確認
wp eval "
\$server = rest_get_server();
\$routes = \$server->get_routes();
foreach (array_keys(\$routes) as \$route) {
    if (strpos(\$route, '/wp/v2/') !== false) {
        echo \$route . PHP_EOL;
    }
}
"

ステップ2:REST APIを妨害している設定を修正する

// REST APIを無効化しているフィルターを確認・削除
// ✗ 以下のようなコードが functions.php にないか確認
add_filter('rest_authentication_errors', fn() => new WP_Error('rest_disabled', 'REST API disabled'));

// ✓ REST APIへのアクセスを特定エンドポイントのみ制限する正しい方法
add_filter('rest_authentication_errors', function(WP_Error|true|null $result): WP_Error|true|null {
    if (! is_user_logged_in() && ! str_starts_with(rest_get_url_prefix(), 'wp-json')) {
        return new WP_Error('rest_not_logged_in', '認証が必要です', ['status' => 401]);
    }
    return $result;
});
# Apache: Authorization ヘッダーを PHP に渡す(.htaccess)
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
# または
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

ステップ3:カスタム投稿タイプをREST APIに対応させる

// register_post_type() で show_in_rest を有効化
register_post_type('product', [
    'label'        => '商品',
    'public'       => true,
    'show_in_rest' => true,              // REST API に公開
    'rest_base'    => 'products',        // /wp-json/wp/v2/products
    'rest_controller_class' => 'WP_REST_Posts_Controller',
    'supports'     => ['title', 'editor', 'thumbnail', 'custom-fields'],
]);

// カスタムフィールドを REST API に公開
register_post_meta('product', 'price', [
    'show_in_rest'   => true,
    'single'         => true,
    'type'           => 'number',
    'auth_callback'  => fn() => current_user_can('edit_posts'),
]);

ステップ4:カスタム REST API エンドポイントを作成する

// カスタムエンドポイントの登録
add_action('rest_api_init', function(): void {
    register_rest_route('myplugin/v1', '/items/(?P<id>\d+)', [
        'methods'             => WP_REST_Server::READABLE,  // GET
        'callback'            => 'my_rest_get_item',
        'permission_callback' => fn() => current_user_can('read'),
        'args'                => [
            'id' => [
                'validate_callback' => fn(string $v) => is_numeric($v),
                'sanitize_callback' => 'absint',
                'required'          => true,
            ],
        ],
    ]);
});

function my_rest_get_item(WP_REST_Request $request): WP_REST_Response|WP_Error {
    $item = get_post($request->get_param('id'));
    if (! $item instanceof WP_Post) {
        return new WP_Error('not_found', '見つかりません', ['status' => 404]);
    }
    return rest_ensure_response(['id' => $item->ID, 'title' => $item->post_title]);
}

ステップ5:REST API 認証とApplication Passwordsを設定する

# Application Passwords を有効化(WordPress 5.6+)
# 管理画面 → ユーザー → プロフィール → アプリケーションパスワード で生成

# 生成したパスワードで認証テスト
APP_PASS="xxxx xxxx xxxx xxxx xxxx xxxx"
curl -s -u "admin:${APP_PASS}" \
    -X POST https://example.com/wp-json/wp/v2/posts \
    -H "Content-Type: application/json" \
    -d '{"title":"テスト投稿","status":"draft"}'
// REST API レスポンスにカスタムフィールドを追加
add_filter('rest_prepare_post', function(WP_REST_Response $response, WP_Post $post): WP_REST_Response {
    $response->data['custom_field'] = get_post_meta($post->ID, 'custom_field', true);
    return $response;
}, 10, 2);

注意事項

  • パーマリンクを「基本」(?p=123形式)に設定しているとREST APIのURLが機能しません。「投稿名」などのモダンなパーマリンク構造に変更してください
  • セキュリティプラグイン(iThemes Security、WordFence等)がREST APIへの未認証アクセスをブロックしている場合があります。プラグインの設定でREST APIを許可してください
  • permission_callback__return_trueを設定すると認証なしでアクセス可能になります。本番環境では必ず適切な権限チェックを実装してください

まとめ

WordPress REST API不動作の解決は①curlでREST APIレスポンスを確認・wp evalでルート一覧を取得・パーマリンク設定が「基本」でないか確認、②セキュリティプラグインのREST API無効化フィルターを削除・Apacheの.htaccessAuthorizationヘッダーをPHPに渡す・NginxはfastcgiパラメーターにHTTP_AUTHORIZATIONを追加、③register_post_type()show_in_rest=trueでカスタム投稿タイプを公開・register_post_meta()show_in_rest=trueでカスタムフィールドを公開、④register_rest_route()でカスタムエンドポイントを作成・permission_callbackで権限チェック・validate_callback/sanitize_callbackで入力値を検証、⑤Application Passwordsでトークンレスな認証・rest_prepare_{type}フィルターでレスポンスにカスタムデータを追加の手順で解決します。

お気軽にご相談ください

お見積りへ お問い合わせへ