HOME / BLOG
BLOG

REST APIを自作してWordPressからJSONを返す

デフォルト画像

WordPressは標準でREST APIを持っていますが、オリジナルテーマや自作ツールを作るなら、自分専用のJSONエンドポイントを作れると便利です。記事一覧、ツール一覧、集計データなどを、好きな形のJSONで返せます。

この記事では、register_rest_routeを使って、WordPressからJSONを返す自作REST APIを作る基本をまとめます。公開APIとログイン必須APIの違いも押さえます。

一番シンプルなREST API

rest_api_initでルートを登録し、callbackで返したいデータを作ります。公開してよい情報ならpermission_callbackに__return_trueを指定できます。

add_action('rest_api_init', function () {
    register_rest_route('nines/v1', '/tools', [
        'methods' => 'GET',
        'callback' => 'nines_get_tools',
        'permission_callback' => '__return_true',
    ]);
});

function nines_get_tools(WP_REST_Request $request): WP_REST_Response
{
    $posts = get_posts([
        'post_type' => 'post',
        'posts_per_page' => 6,
        'category_name' => 'tool',
    ]);

    $data = array_map(function (WP_Post $post) {
        return [
            'id' => $post->ID,
            'title' => get_the_title($post),
            'url' => get_permalink($post),
            'date' => get_the_date('Y-m-d', $post),
        ];
    }, $posts);

    return rest_ensure_response($data);
}

URLの例

https://example.com/wp-json/nines/v1/tools

パラメータ付きでJSONを返す

カテゴリーや件数を指定できるようにすると、フロント側の表示に使いやすくなります。per_pageの上限を決めておくと、重すぎるリクエストを防げます。

add_action('rest_api_init', function () {
    register_rest_route('nines/v1', '/posts', [
        'methods' => 'GET',
        'callback' => 'nines_get_filtered_posts',
        'permission_callback' => '__return_true',
        'args' => [
            'category' => [
                'sanitize_callback' => 'sanitize_key',
                'default' => 'blog',
            ],
            'per_page' => [
                'sanitize_callback' => 'absint',
                'default' => 5,
            ],
        ],
    ]);
});

function nines_get_filtered_posts(WP_REST_Request $request): WP_REST_Response
{
    $per_page = min(20, max(1, (int) $request['per_page']));

    $query = new WP_Query([
        'post_status' => 'publish',
        'posts_per_page' => $per_page,
        'category_name' => $request['category'],
    ]);

    $items = [];
    foreach ($query->posts as $post) {
        $items[] = [
            'id' => $post->ID,
            'title' => get_the_title($post),
            'excerpt' => wp_strip_all_tags(get_the_excerpt($post)),
            'url' => get_permalink($post),
        ];
    }

    return rest_ensure_response([
        'count' => count($items),
        'items' => $items,
    ]);
}

ログイン必須のREST API

管理者向けダッシュボードやメモ保存など、誰でも使えてはいけないAPIはpermission_callbackで権限チェックします。ここを省略すると危険です。

add_action('rest_api_init', function () {
    register_rest_route('nines/v1', '/private-memo', [
        'methods' => 'POST',
        'callback' => function (WP_REST_Request $request) {
            return rest_ensure_response([
                'message' => sanitize_textarea_field($request['message']),
                'saved' => true,
            ]);
        },
        'permission_callback' => function () {
            return current_user_can('edit_posts');
        },
    ]);
});

よくある失敗

  • permission_callbackを書かず、警告や意図しない公開につながる
  • 入力値をsanitizeせず、そのままWP_Queryへ渡す
  • 件数制限を入れず、大量データを返してしまう
  • HTMLを返すべき場所とJSONを返す場所を混ぜる
  • キャッシュしないまま重い集計APIを公開する

参考資料

まとめ

自作REST APIを作れるようになると、WordPressをただのブログではなく、データを返すCMSとして扱いやすくなります。公開APIはシンプルに、管理者向けAPIは権限チェックを強めに、という切り分けで作るのが安全です。