tenjuu99/wp-resta

使用DI(依赖注入)的WordPress REST API开发框架

安装: 102

依赖: 0

建议者: 0

安全: 0

星标: 4

关注者: 1

分支: 0

开放问题: 1

类型:wordpress-plugin

v0.8.4 2024-06-07 09:03 UTC

This package is auto-updated.

Last update: 2024-09-07 09:30:29 UTC


README

Continuous Integration

Wp\Resta

这是一个用于在WordPress上开发REST API的插件。

该插件的理念和接口受到了BEAR.Sunday 的影响。

如何安装

前提:请确保在WordPress管理面板中将永久链接设置保存为“文章标题”等。

用于自定义主题

$ cd /path/to/theme
$ composer require tenjuu99/wp-resta

functions.php 中初始化

以下是从示例目录中读取API的设置示例。

<?php
require_once __DIR__ . '/vendor/autoload.php';

(new Wp\Resta\Resta)->init([
    'routeDirectory' => [
        [__DIR__ . '/vendor/wp/resta/src/REST/Example/Routes', 'Wp\\Resta\\REST\\Example\\Routes\\', 'example']
    ],
    'use-swagger' => true,
    'schemaDirectory' => [
        [__DIR__ . '/vendor/wp/resta/src/REST/Example/Schemas', 'Wp\\Resta\\REST\\Example\\Schemas\\'],
    ],
]);

作为插件使用

也可以将其作为WordPress插件使用。

以下示例使用 composer/installers 将WordPress插件配置到 wp-content/plugins/ 以下。

$ composer config "extra.installer-paths.wp-content/plugins/{\$name}/" "['type:wordpress-plugin']"
$ composer require composer/installers tenjuu99/wp-resta

如果成功展开到wp-content/plugins以下,请从管理面板启用插件。

示例

安装后,管理面板将添加一个名为 REST API doc 的菜单。

此页面使用Swagger UI对API定义进行文档化。

此示例实现位于 src/REST/Example/Routes/ 以下。

如何开发

要添加自己的路由定义,请在 functions.php 初始化时编写路由目录的设置代码。

传递给 routeDirectory 的数组是 ['目录名', 'php命名空间', 'api命名空间'],而 schemaDirectory['目录名', 'php命名空间']

(new Wp\Resta\Resta)->init([
    'routeDirectory' => [
        ['wp-content/themes/mytheme/vendor/wp/resta/src/REST/Example/Routes', 'Wp\\Resta\\REST\\Example\\Routes\\', 'example'],
+       ['src/Routes', 'MyREST\\Routes\\', 'myroute']
    ],
    'schemaDirectory' => [
        ['wp-content/themes/mytheme/vendor/wp/resta/src/REST/Example/Schemas', 'Wp\\Resta\\REST\\Example\\Schemas\\'],
+       ['src/Schemas', 'MyREST\\Schemas\\']
    ],
]);

根据需要,在 composer.json 中添加autoload设置。

  "autoload": {
+     "psr-4": {
+         "MyREST\\": "src/"
+     }
  }

创建 src/Routes/HelloWorld.php

<?php
namespace MyREST\Routes;

use Wp\Resta\REST\AbstractRoute;

class HelloWorld extends AbstractRoute
{
    public $body = 'Hello, world!';
}

以下URL将被生成。

$ curl http://example.com/wp-json/myroute/helloworld

请确保返回值为 "Hello, world!"。

URL定义和URL变量

myroute 是在 functions.php 中定义的命名空间,而 helloworld 则直接用作类名。

通过定义 ROUTE 常量来更改URL定义。同时,让我们定义一些URL变量。

<?php
namespace MyREST\Routes;

use Wp\Resta\REST\AbstractRoute;

class HelloWorld extends AbstractRoute
{
    protected const ROUTE = 'hello/[name]';
    protected const URL_PARAMS = [
        'name' => 'string',
    ];

    public function callback(string $name) : string
    {
        return "Hello, ${name}!";
    }
}

我们期望生成以下URL。

$ curl http://example.com/wp-json/myroute/hello/amashige

我们期望返回 "Hello, amashige!"。

ROUTE 常量中,使用 [var][] 包围即可将参数作为路径参数处理。

变量允许以下模式。

    protected const URL_PARAMS = [
        'id' => 'integer',
        'id_not_required' => '!integer',
        'name' => 'string',
        'name_not_required' => '!string',
        'ok_or_ng' => '(ok|ng)',
        'first_name' => [
            'type' => 'string',
            'required' => false,
            'regex' => '[a-z]+'
        ],
    ];

这些可以通过将 ROUTE 常量定义为 user/[id] 的形式作为URL嵌入变量来定义为路径参数。

未作为路径参数使用的但定义在 URL_PARAMS 中的变量作为查询参数使用。

以下示例展开为 http://example.com/wp-json/myroute/user/2?name=tenjuu99

    protected const ROUTE = 'user/[id]';
    protected const URL_PARAMS = [
        'id' => 'integer',
        'name' => '?string',
    ];

这些变量可以通过回调方法接收。

回调

如果继承自 AbstractRoute 的类有一个名为 callback 的方法,则可以调用此方法以将其用作响应的body。可以作为body返回的是可以被 WP_REST_Response 解析的对象。如果返回了 Psr\Http\Message\ResponseInterface,则将其直接使用。

callback 方法的参数可以接收URL变量。如果定义了 URL变量 id,则可以将其定义为 callback(int $id)

此外,由于存在简单的DI,因此可以将可解决的类作为参数定义以接收。对于在运行时确定值(例如 WP_REST_Response)的情况,由于在回调被调用时值已确定,因此可以使用它们。

DI

提供了一个简单的DI。

基本上是自动绑定,在大多数情况下无需设置即可使用。基本上只支持构造函数注入(AbstractRoute::callback 是例外)。

// src/Lib/Foo.php
namespace MyREST\Lib;

class Foo
{
    private Bar $bar;

    public function __construct(Bar $bar)
    {
        $this->bar = $bar;
    }

    public function getBarString(): string
    {
        return $this->bar->get();
    }
}

// src/Lib/Bar.php
namespace MyREST\Lib;

class Bar
{
    public function get(): string
    {
        return 'bar';
    }
}

// src/Routes/Sample.php

namespace MyREST\Routes;

use MyREST\Lib\Foo;

class Sample extends AbstractRoute
{
    private Foo $foo;
    public function __construct(Foo $foo)
    {
        $this->foo = $foo;
    }

    public function callback()
    {
        return $this->foo->getBarString();
    }
}

Bar::get 的返回值将被解决。

上述内容可以通过DI的自动绑定来解决,但如果是接口注入,则无法自动解决。在这种情况下,需要进行设置。设置可以通过将 dependencies 传递给初始化代码来完成。

(new Wp\Resta\Resta)->init([
    'routeDirectory' => [
    ...
    ],
    'schemaDirectory' => [
    ...
    ],
+   'dependencies' => [
+       PSR\Log\LoggerInterface::class => MonoLog\Logger::class,
+   ],
]);

此外,自动绑定机制仅解决类或接口的依赖,因此如果构造函数接收类或接口以外的值,则无法解决。在这种情况下,请使用函数。

(new Wp\Resta\Resta)->init([
    'routeDirectory' => [
    ...
    ],
    'schemaDirectory' => [
    ...
    ],
    'dependencies' => [
        PSR\Log\LoggerInterface::class => MonoLog\Logger::class,
+       WP_Query::class => function () {
+           return new WP_Query(['post_type' => 'post']);
+       }
    ],
]);