2026年8月15日
2026年8月15日
WordPressのカスタム投稿タイプをREST APIに対応させる設定(show_in_rest)
カスタム投稿タイプを REST API で読み書きできるようにするには、register_post_type() の引数に 'show_in_rest' => true を加えるのが基本です。自作の投稿タイプならその一行で /wp-json/wp/v2/{rest_base} が使えるようになり、プラグインが登録した投稿タイプは register_post_type_args フィルターで後から有効にできます。この記事では、エンドポイント名の決め方、タクソノミーとカスタムフィールドの公開、認証、動かないときの確認順までをまとめます。
なぜ show_in_rest が必要なのか
WordPress の REST API は、登録時に REST への公開を許可された投稿タイプだけをエンドポイントとして出します。show_in_rest の既定値は false なので、何も指定せずに登録したカスタム投稿タイプは /wp-json/wp/v2/ 配下に現れません。
この設定は外部連携のためだけのものではありません。ブロックエディターは編集画面の読み書きに REST API を使うため、show_in_rest が false の投稿タイプはクラシックエディターの画面で開かれます。「カスタム投稿タイプだけブロックエディターにならない」という症状の原因も、多くはこの設定です。
自作の投稿タイプに REST 対応を加える
登録コードはテーマではなく独自プラグインか mu-plugin に置くのがおすすめです(テーマに書く場合は子テーマを使います)。変更前にバックアップを取り、ステージングで確認してから本番に反映してください。
<?php
add_action( 'init', 'myprefix_register_book_post_type' );
function myprefix_register_book_post_type() {
register_post_type(
'book',
array(
'labels' => array(
'name' => '書籍',
'singular_name' => '書籍',
),
'public' => true,
'has_archive' => true,
'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt', 'custom-fields' ),
'show_in_rest' => true,
'rest_base' => 'books',
)
);
}
関係する引数は次のとおりです。
show_in_rest:REST API への公開を有効にします。rest_base:URLに使う名前です。省略すると投稿タイプ名(この例ではbook)がそのまま使われます。複数形にしたい、既存の連携先に合わせたいといった理由がある場合に指定します。rest_namespace:名前空間を変える引数で、既定はwp/v2です。WordPress 5.9 で追加されたもので、通常は変更する必要はありません。rest_controller_class:処理を担当するクラスです。既定のWP_REST_Posts_Controllerで足りることがほとんどです。
supports の custom-fields は、後述するカスタムフィールドを REST のレスポンスに含めるために入れています。
プラグインが登録した投稿タイプを後から対応させる
他のプラグインやテーマが登録した投稿タイプは、元のコードを書き換えずに register_post_type_args フィルターで引数を差し替えます。元のファイルを直接編集すると、更新のたびに上書きされて消えてしまうためです。
<?php
add_filter( 'register_post_type_args', 'myprefix_enable_rest_for_event', 10, 2 );
function myprefix_enable_rest_for_event( $args, $post_type ) {
if ( 'event' !== $post_type ) {
return $args;
}
$args['show_in_rest'] = true;
if ( empty( $args['rest_base'] ) ) {
$args['rest_base'] = 'events';
}
return $args;
}
このフィルターは、対象の投稿タイプが登録される前に読み込まれている必要があります。mu-plugin に置くと読み込み順の心配が少なくなります。なお、もともと REST を無効にしている投稿タイプには、管理画面だけで使う前提の内部データが入っていることもあります。公開してよい内容かを先に確認してください。
タクソノミーとカスタムフィールドも公開する
投稿本体だけを REST に出しても、カテゴリーやカスタムフィールドが含まれないと連携先で使いにくくなります。
タクソノミー
カスタムタクソノミーも show_in_rest を指定しないと REST に出ず、ブロックエディターのサイドバーにも選択欄が表示されません。
<?php
add_action( 'init', 'myprefix_register_genre_taxonomy' );
function myprefix_register_genre_taxonomy() {
register_taxonomy(
'genre',
'book',
array(
'label' => 'ジャンル',
'hierarchical' => true,
'show_in_rest' => true,
'rest_base' => 'genres',
)
);
}
有効にすると、書籍のレスポンスに genres としてタームIDの配列が含まれ、/wp-json/wp/v2/genres でターム一覧も取れるようになります。
カスタムフィールド(投稿メタ)
投稿メタは register_post_meta() で型と公開範囲を登録して初めて REST に出ます。未登録のメタは、値が保存されていてもレスポンスの meta には現れません。
<?php
add_action( 'init', 'myprefix_register_book_meta' );
function myprefix_register_book_meta() {
register_post_meta(
'book',
'isbn',
array(
'type' => 'string',
'single' => true,
'show_in_rest' => true,
'sanitize_callback' => 'sanitize_text_field',
'auth_callback' => function ( $allowed, $meta_key, $post_id ) {
return current_user_can( 'edit_post', $post_id );
},
)
);
}
sanitize_callback で保存前の値を整え、auth_callback で書き込みできるユーザーを絞ります。読み取りは、投稿自体を読めるユーザーなら誰でも可能になる点を理解しておいてください。会員限定の情報や内部メモのように外に出したくない値は、show_in_rest を有効にしないでおきます。
複数のメタをまとめた値や計算結果を返したい場合は、register_rest_field() で独自のフィールドを追加する方法もあります。こちらは get_callback で返す値を自分で組み立てる仕組みで、schema を書いておくと型の検証にも使われます。
動作を確認する
ブラウザやコマンドで、次の順に確認します。
# 投稿タイプが REST に登録されているか
curl -s https://example.com/wp-json/wp/v2/types/book
# 公開済みの書籍を取得(必要な項目だけに絞る)
curl -s "https://example.com/wp-json/wp/v2/books?per_page=5&_fields=id,title,link,genres,meta"
一件目で投稿タイプの情報が返れば登録は成功しています。二件目のレスポンスヘッダーにある X-WP-Total と X-WP-TotalPages で、総件数とページ数も確認できます。_fields を付けると不要な項目を省けるので、連携先の処理も軽くなります。
認証が必要な操作
未ログインで取得できるのは、公開済みの投稿だけです。下書きの取得や、投稿の作成・更新・削除には認証が必要で、権限は通常の WordPress と同じく edit_posts などのユーザー権限で判定されます。
- 同じサイト内の JavaScript から呼ぶ場合:ログイン中のクッキーに加えて、
wp_create_nonce( 'wp_rest' )で作った nonce をX-WP-Nonceヘッダーで送ります。nonce がないとログイン中でも未ログイン扱いになります。 - 外部のシステムから呼ぶ場合:WordPress 5.6 以降で使えるアプリケーションパスワードが手軽です。ユーザーのプロフィール画面で発行し、Basic 認証で送ります。HTTPS 上でのみ使い、連携専用のユーザーを作って必要最小限の権限にとどめてください。
アプリケーションパスワードは通常のログインパスワードとは別物で、個別に失効させられます。コードやリポジトリに直接書かず、環境変数などで管理します。
動かないときの確認順
**rest_no_route(404)が返る。** 最も多いのは show_in_rest が効いていないケースです。フィルターで変更した場合は読み込み順を疑います。次に、URLが rest_base と一致しているかを確認します。パーマリンク設定が「基本」のサイトでは /wp-json/ が使えないため、?rest_route=/wp/v2/books の形で試してください。
一覧は返るのに下書きが含まれない。 認証なしの正常な動作です。status=draft を付けて認証つきで呼ぶと取得できます。
**meta が空、または項目自体がない。** register_post_meta() で show_in_rest を有効にしているか、supports に custom-fields があるかを確認します。
**rest_forbidden や 401 が返る。** 認証情報が届いていないか、ユーザーの権限が足りません。セキュリティ系のプラグインや WAF が REST API へのアクセスを制限していることもあるので、その設定も見直してください。
REST API の挙動や関連する引数は WordPress のバージョンで追加・変更されることがあります。本記事の説明は執筆時点(2026年10月現在)のものなので、使っているバージョンの公式リファレンスも合わせて確認してください。
まとめ
- カスタム投稿タイプを REST に出すには
'show_in_rest' => true。ブロックエディターを使うためにも必要。 - URL名は
rest_baseで決められ、他のプラグインの投稿タイプはregister_post_type_argsで後から有効にできる。 - タクソノミーは
register_taxonomy()のshow_in_rest、メタはregister_post_meta()で個別に公開範囲を決める。 - 読み取りは公開済みのみ、書き込みや下書きは nonce またはアプリケーションパスワードで認証する。
- 公開してよいデータかを確かめてから有効にする。