fabricio872 / api-modeller
用于将外部API翻译成Doctrine-like模型的库
Requires
- php: ^7.2|^8.0
- ext-json: *
- doctrine/annotations: ^1.13
- doctrine/collections: ^1.6
- symfony/http-client: ^4.4|^5|^6
- symfony/property-access: ^4.4|^5|^6
- symfony/serializer: ^4.4|^5|^6
- twig/twig: ^3.3
Requires (Dev)
- phpunit/phpunit: ^8.5
- symplify/easy-coding-standard: ^9.4
This package is auto-updated.
Last update: 2024-09-29 06:20:05 UTC
README
有价值的合作伙伴
安装前
如果您使用的是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