WordPressをHeadlessCMSとして使いたいと思い、WordPressが用意しているREST APIではなく、独自のエンドポイントを作りたいと考えました。
通常、独自のエンドポイントを設定する場合は rest_api_initのアクションフックを使用します。
WP REST API を使って独自エンドポイントを設定する。
しかし、もう少し構造化したいと思い、便利そうだと感じたのがWp\Restaでした。
今回はbedrockとWp\Restaを使用してWordPressを設定する手順を書いていきます。
Bedrockでプロジェクトを生成する
公式ドキュメントに従い、 composer create-project でプロジェクトを生成します。
1
|
$ composer create-project roots/bedrock
|
Wp\Restaのインストールと設定
Wp\Restaもcomposerでインストールします。
1
|
$ composer req tenjuu99/Wp\Resta
|
config/resta.phpファイルを作成して設定を記述する
Wp\Resta用の設定ファイル config/resta.php
を作成し、以下の内容を記述します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<?php
$rootDir = dirname(__DIR__);
return [
'autoloader' => $rootDir . '/vendor/autoload.php',
'routeDirectory' => [
[$rootDir . '/src/Route', 'App\\Route\\', 'custom'],
],
'use-swagger' => true,
'schemaDirectory' => [
[$rootDir . '/src/Schema', 'App\\Schema\\'],
],
'dependencies' => [
],
];
|
オートローダーの場所やルーティング用のクラスを配置するディレクトリ、スキーマを配置するディレクトリを指定します。今回はsrc ディレクトリにソースコードを配置します。
Wp\Restaの設定ファイルを読み込ませる。
Wp\Restaは RESTA_CONFIG_FILE
という環境変数で設定ファイルの位置を指定できます。
基本的には環境ごとに差異が発生するわけでもないので config/application.php
でputenv
を使用して設定ファイルのパスを指定します。
1
2
3
4
5
6
|
// config/application.php
/**
* resta config
*/
putenv('RESTA_CONFIG_FILE=' . $root_dir .'/config/resta.php');
|
composer.jsonのオートローダーの設定
src以下を App
namespaceとして指定するため、composer.jsonに以下の設定を追記します。
1
2
3
4
5
|
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
|
実際に独自エンドポイントを定義してみる
以下のようにエンドポイントを定義します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
// src/Route/HelloWorld.php
<?php
namespace App\Route;
use Wp\Resta\REST\AbstractRoute;
class HelloWorld extends AbstractRoute
{
public function callback(): array
{
return [
'message' => 'Hello World!',
];
}
}
|
この状態でhttpリクエスト送ると「Hello World!」と表示されます。
1
2
|
$ curl http://localhost/wp-json/custom/helloworld
{"message":"Hello World!"}
|
URLパラメータの扱いについて
ページ一覧を取得する場合に page
のクエリパラメータを受け取るためには、 URL_PARAMS
クラス定数に定義します。
よくあるページ一覧みたいなのを取得したい場合に page
のクエリパラメータを受け取りたいかと思います。
その場合はURL_PARAMSのクラス定数に定義してあげれば大丈夫です。
定義できるのは string,integerで必須かどうかは先頭に?
をつけるかで変わってきます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
final class News extends AbstractRoute
{
protected const URL_PARAMS = [
'page' => '?integer',
'limit' => '?integer',
];
public function callback(int $page = 1, int $limit = 1): array
{
$offset = ($page - 1) * $limit;
$wpQuery = new \WP_Query();
$posts = $wpQuery->query([
'post_type' => 'post',
'post_status' => 'publish',
'orderby' => 'date',
'order' => 'DESC',
'offset' => $offset,
'posts_per_page' => $limit,
]);
$totalPosts = $wpQuery->found_posts;
$maxPages = (int)ceil($totalPosts / (int)$wpQuery->query_vars['posts_per_page']);
return [
'totalPosts' => $wpQuery->found_posts,
'totalPages' => $maxPages,
'posts' => array_map(static function (WP_Post $post) {
return [
'title' => $post->post_title,
'content' => apply_filters('the_content', $post->post_content),
'date' => $post->post_date,
];
}, $posts),
];
}
}
|
レスポンスヘッダを定義したい
レスポンスヘッダを追加で定義したい場合は $this->headers
で使用します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
final class News extends AbstractRoute
{
protected const URL_PARAMS = [
'page' => '?integer',
'limit' => '?integer',
];
public function callback(int $page = 1, int $limit = 1): array
{
$this->headers = [
'X-POLIDOG-NUMBER' => random_int(0, 100000),
];
$offset = ($page - 1) * $limit;
$wpQuery = new \WP_Query();
$posts = $wpQuery->query([
'post_type' => 'post',
'post_status' => 'publish',
'orderby' => 'date',
'order' => 'DESC',
'offset' => $offset,
'posts_per_page' => $limit,
]);
$totalPosts = $wpQuery->found_posts;
$maxPages = (int)ceil($totalPosts / (int)$wpQuery->query_vars['posts_per_page']);
return [
'totalPosts' => $wpQuery->found_posts,
'totalPages' => $maxPages,
'posts' => array_map(static function (WP_Post $post) {
return [
'title' => $post->post_title,
'content' => apply_filters('the_content', $post->post_content),
'date' => $post->post_date,
];
}, $posts),
];
}
}
|
最後に
この構成の良い点は、WordPress、プラグイン、自分たちの拡張がうまく分離できることです。通常はWordPressやプラグインでしか拡張ポイントを作れませんが、自分たちの拡張を src/
配下に設置できるのはメリットです。
Wp\RestaはWordPress内で使える優れたREST APIフレームワークであり、Bedrockなしでも使える便利なプラグインです。
WordPressで独自のREST APIを作る場合はWp\Restaを使ってみることをおすすめします。