fabricio872/api-modeller

用于将外部API翻译成Doctrine-like模型的库

安装量: 1,666

依赖: 1

建议者: 0

安全: 0

星标: 0

关注者: 1

分支: 0

开放问题: 0

类型:symfony-bundle

v2.2.4 2022-06-29 11:58 UTC

README

GitHub release GitHub last commit PHP Composer Test and Tag Packagist Downloads GitHub Repo stars

有价值的合作伙伴

PhpStorm logo

安装前

如果您使用的是7.2之前的旧版php,请使用以下命令下载:

$ composer require fabricio872/api-modeller:^1.0

安装

请确保已全局安装Composer,如Composer文档中的安装章节所述。

步骤 1:下载库

打开命令行,进入您的项目目录,并执行以下命令以下载此包的最新稳定版本

$ composer require fabricio872/api-modeller

步骤 2:初始化库

创建一个 Fabricio872\ApiModeller\Modeller 的新实例。对于遗留项目,使用单例模式实现它是最简单的,这样您可以在任何需要调用它的地方调用它,如此处所述。

为您的客户端适配器创建一个新类。在这个例子中,我们使用 GuzzleHttp/Client

use Fabricio872\ApiModeller\ClientAdapter\ClientInterface;
use GuzzleHttp\Client;

class GuzzleClient implements ClientInterface
{
    private Client $client;

    public function __construct()
    {
        $this->client = new Client();
    }

    public function request(string $method, string $endpoint, array $options): string
    {
        return $this->client->request($method, $endpoint, $options)->getBody()->getContents();
    }
}

在您的composer自动加载目录中的某个位置创建一个名为Modeller的新类,并添加您的命名空间

use Doctrine\Common\Annotations\AnnotationReader;
use Fabricio872\ApiModeller\ClientAdapter\Symfony;
use Symfony\Component\HttpClient\HttpClient;
use Twig\Environment;
use Twig\Loader\FilesystemLoader;

class Modeller
{
    /** @var \Fabricio872\ApiModeller\Modeller */
    private static $modeller;

    public static function get()
    {
        if (!isset(self::$modeller)) {
            $reader = new AnnotationReader();

            $client = new GuzzleClient(); // class we have created above

            $loader = new FilesystemLoader();
            $twig = new Environment($loader, [
                'cache' => '/path/to/compilation_cache',
            ]);

            self::$modeller = new \Fabricio872\ApiModeller\Modeller(
                $reader,
                $client,
                $twig
            );
        }
        return self::$modeller;
    }
}

用法

此库使用与Doctrine实体相似的注解模型。

通常它们位于 src/ApiModels 目录中,但只要它们有正确的命名空间,就无需位于那里。

具有单个资源的示例模型

这是从某些API接收用户列表的模型示例

// src/ApiModels/Users.php

use Fabricio872\ApiModeller\Annotations\Resource;

/**
 * @Resource(
 *     endpoint="{{api_url}}/api/users",
 *     method="GET",
 *     type="json",
 *     options={
 *          "headers"={
 *              "accept"= "application/json"
 *          }
 *     }
 * )
 */
class Users
{
    public $page;
    public $per_page;
    public $total;
    public $total_pages;
    public $data;
}

endpoint参数是要调用的端点。

method参数是执行请求的方法。

默认值: "GET"

type参数定义接收数据的格式。

目前支持: "json", "xml"

默认值: "json"

options参数是一个数组,直接传递(但可以在setOptions部分中进行修改)到symfony/http-client请求方法作为第三个参数,因此请使用此文档

具有多个资源的示例模型

要定义多个资源,您需要将多个Resource注解包装在单个Resources注解中,并在开头使用标识符。然后在调用此端点时使用此标识符,如setIdentifier部分所述。

// src/ApiModels/Users.php

use Fabricio872\ApiModeller\Annotations\Resource;
use Fabricio872\ApiModeller\Annotations\Resources;

/**
 * @Resources({
 *      "multiple"= @Resource(
 *          endpoint="{{api_url}}/api/users",
 *          method="GET",
 *          type="json",
 *          options={
 *              "headers"={
 *                  "accept"= "application/json"
 *              }
 *          }
 *      ),
 *      "single"= @Resource(
 *          endpoint="{{api_url}}/api/users/{{id}}",
 *          method="GET",
 *          type="json",
 *          options={
 *              "headers"={
 *                  "accept"= "application/json"
 *              }
 *          }
 *      ),
 * })
 */
class Users
{
    public $page;
    public $per_page;
    public $total;
    public $total_pages;
    public $data;
}

调用API

如果配置如此处所述,则可以像这样接收Fabricio872\ApiModeller\Modeller类的实例:

此控制器以命名空间 Users::class 和将查询参数 'page' 设置为 2 的形式输出此示例中的模型或模型集合

// src/Controller/SomeController.php

    public function index()
    {
        var_dump(Modeller::get()->getData(
            Repo::new(Users::class)
                ->setOptions([
                    "query" => [
                        "page" => 2
                    ]
                ])
        ));
    }

注意,setOptions具有替代功能addOptions,它合并现有和提供的选项

请注意,Modeller::get()必须具有指向配置部分中类的正确命名空间

此控制器以命名空间 Users::class 的形式输出此示例中的模型或模型集合,并使用数字 2 填充模型中的{{id}}变量

注意现在方法 setIdentifier 是必需的

// src/Controller/SomeController.php

    public function index(Modeller $modeller)
    {
        var_dump(Modeller::get()->getData(
            Repo::new(Users::class)
                ->setParameters([
                    "id" => 2
                ])
                ->setIdentifier("single")
        ));
    }

模型器接受 Repo 对象,该对象需要构建模型的命名空间,并且有可选的设置器

  • setOptions()
  • setParameters()
  • setIdentifier()

setOptions

此方法接受选项数组,这些选项将与模型中配置的选项合并(并将覆盖重叠的参数),作为 3. 参数用于 symfony/http-client 请求方法,请使用 此文档

setParameters

此方法接受数组并设置 twig 变量(与渲染模板时相同,但在这里模板是来自模型的端点参数),并可以覆盖全局 twig 变量

setIdentifier

当您使用多个资源为单个模型时,此方法是必需的,如 此示例 所示

模型标题

模型标题在数据到达时覆盖在其他对象中时很有用,如下所示

{
  "data": [
    {
      "myData": "data"
    }
  ]
}

在这种情况下,您的模型将具有标题 data 以直接将模型变量映射到 myData 而不是映射到 data 对象

// src/ApiModels/Data.php

use Fabricio872\ApiModeller\Annotations\Resource;
use Fabricio872\ApiModeller\Annotations\ModelTitle;

/**
 * @Resource(
 *     endpoint="{{api_url}}/api/data",
 *     method="GET",
 *     type="json",
 *     options={
 *          "headers"={
 *              "accept"= "application/json"
 *          }
 *     }
 * )
 * @ModelTitle("data")
 */
class Data
{
    public $myData;
}

您还可以将 ModelTitles 嵌套到数组中,并为每个标题提供多个选项,例如

/**
 * @ModelTitle("data", {"subTitle1", "subTitle2"})
 */

这将搜索传入的响应中的数据,并在其中搜索 subTitle1 或 subTitle2