WordPressのREST APIエンドポイントを追加する方法

WordPressのREST APIは/wp-jsonから始まるパスで提供されており、独自のAPIを追加して外部サービスと連携する方法を紹介しています。rest_api_initフックでregister_rest_routeを使用し、プラグインコードを追加するとAPIが追加されます。第一・第二引数で指定したパスでAPIにアクセスすることができ、APIの情報は自動的に登録されます。また、正規表現を使用してパスに商品や店舗のIDなどを渡すこともできます。さらに、バリデーション処理を追加することで、リクエスト内容のバリデーションとエラーメッセージの表示が可能です。最後に、WordPressのREST APIを活用することで、ブロック開発に役立つことも紹介されています。

広告ここから
広告ここまで

目次

    WordPressが提供するREST APIは/wp-jsonから始まるパスで提供されています。ここに独自のAPIを追加して、外部サービスと連携するAPIを追加したりする方法をまとめました。

    rest_api_initフックでregister_rest_routeする

    ミニマムのプラグインコードがこちらです。Hello Dollyプラグインあたりのコードを上書きすると簡単に試せます。

    <?php
    /**
     * Plugin Name:       Wp Playground
     * Description:       Example.
     * Requires at least: 6.1
     * Requires PHP:      7.0
     * Version:           0.1.0
     * Author:            The WordPress Contributors
     * License:           GPL-2.0-or-later
     * License URI:       https://www.gnu.org/licenses/gpl-2.0.html
     * Text Domain:       wp-playground
     *
     */
    
    if ( ! defined( 'ABSPATH' ) ) {
        exit; // Exit if accessed directly.
    }
    
    add_action( 'rest_api_init', function () {
        register_rest_route(
            'my_plugin/v1',
            'hello',
            [
                'method' => 'GET',
                'callback' => function () {
                    return "Hello!";
                }
            ]
        );
    });

    このコードを含むプラグインを有効化していると、第一・第二引数で指定したパスでAPIが増えています。

    % curl http://localhost:8881/wp-json/my_plugin/v1/hello
    "Hello!"%                                

    APIの情報も自動て登録される

    第一引数がネームスペースのような扱われ方をします。そのため、ネームスペースレベルのパスでGETを投げると、「こんなパスでこんなAPIが使えるよ」という情報が見れるようになっています。

    % curl http://localhost:8881/wp-json/my_plugin/v1 | jq .
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
      0     0    0     0    0     0      0      0 --:--:-- --:100   631    0   631    0     0   1305      0 --:--:-- --:100   631    0   631    0     0   1304      0 --:--:-- --:--:-- --:--:--  1320
    {
      "namespace": "my_plugin/v1",
      "routes": {
        "/my_plugin/v1": {
          "namespace": "my_plugin/v1",
          "methods": [
            "GET"
          ],
          "endpoints": [
            {
              "methods": [
                "GET"
              ],
              "args": {
                "namespace": {
                  "default": "my_plugin/v1",
                  "required": false
                },
                "context": {
                  "default": "view",
                  "required": false
                }
              }
            }
          ],
          "_links": {
            "self": [
              {
                "href": "http://localhost:8881/index.php/wp-json/my_plugin/v1"
              }
            ]
          }
        },
        "/my_plugin/v1/hello": {
          "namespace": "my_plugin/v1",
          "methods": [
            "GET"
          ],
          "endpoints": [
            {
              "methods": [
                "GET"
              ],
              "args": []
            }
          ],
          "_links": {
            "self": [
              {
                "href": "http://localhost:8881/index.php/wp-json/my_plugin/v1/hello"
              }
            ]
          }
        }
      },
      "_links": {
        "up": [
          {
            "href": "http://localhost:8881/index.php/wp-json/"
          }
        ]
      }
    }

    リクエストに応じたレスポンスを作る

    AP Iのパスに商品や店舗のIDなどを渡したい場合、register_rest_routeの第二引数に正規表現でパスを指定します。

    
        register_rest_route(
            'my_plugin/v1',
            'hello/(?P<message>.+)',
            [
                'method' => 'GET',
                'callback' => function ( WP_REST_Request $request ) {
                    return "Hello " . $request['message'];
                }
            ]
        );

    • 文字列をmessageで受け取りたい場合の例: (?P<message>.+)
    • 数字を受け取りたい場合の例: (?P\d+)

    このAPIを呼び出すと、パスの内容がそのままでてきます。実際に使う場合は、XSSなどの対策を受け取った内容に対して施すようにしましょう。

    % curl http://localhost:8881/wp-json/my_plugin/v1/hello/world
    "Hello world"

    リクエスト内容のバリデーションを事前に行う

    バリデーションとエラーメッセージの表示などは、validation_callbackで簡単に実装できます。例えば次のコードでは、messageに数字を渡すことを禁止しています。

       register_rest_route(
            'my_plugin/v1',
            'hello/(?P<message>.+)',
            [
                'method' => 'GET',
                'args' => [
                    'message' => [
                        'validate_callback' => function( $param ) {
                            return !is_numeric( $param );
                        },
                    ]
                ],
                'callback' => function ( WP_REST_Request $request ) {
                    return "Hello " . $request['message'];
                }
            ]
        );

    このAPIに123などの数字を渡すと、HTTP400エラーが返ってきます。

    % curl http://localhost:8881/wp-json/my_plugin/v1/hello/123 | jq
     .
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
      0     0    0     0    0     0      0      0 --:--:-- --:100   148    0   148    0     0    529      0 --:--:-- --:--:-- --:--:--   542
    {
      "code": "rest_invalid_param",
      "message": "Invalid parameter(s): message",
      "data": {
        "status": 400,
        "params": {
          "message": "Invalid parameter."
        },
        "details": []
      }
    }

    バリデーション処理だけつければ、検証とエラーメッセージの表示を任せれるのはありがたいですね。

    おわりに

    定期的にお世話になっている割には、書き方をまとめていなかったので簡単に記事化しました。ブロックでの開発がデフォルトになると、この辺りのAPIのお世話になることも増えそうなので、皆さんもぜひお試しください。

    参考記事

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark