sudiptochoudhury/php-api-client-forge

在PHP中创建RESTful API客户端

v0.4.2 2024-04-11 08:07 UTC

README

使用最少的代码从Postman集合数据(或其他来源)在PHP中创建RESTful API客户端

php-api-client-forge

  • 从Postman集合数据(或其他来源)创建RESTful API客户端类
  • 自动生成class @method文档用于phpDoc
  • 自动生成Markdown API文档

Latest Stable Version Latest Unstable Version License Total Downloads composer.lock available

从Postman导出的JSON导入API定义到与Guzzle\Description格式兼容的JSON或传递一个GuzzleHttp\Command\Guzzle\Description对象,您的API类即可使用。

作为奖励,您还将获得一个自动生成的Markdown格式的API文档。此外,您将获得一个包含@method声明的PHP文件,用于phpDoc类文档。

此软件包需要作为父软件包使用。通过扩展Client类来创建您自己的API类。

此软件包专门设计用于导入以JSON格式导出的Postman集合(集合v2.1 - Schema)。

基础知识

<?php

namespace My\Namespace\ApiProvider;

use SudiptoChoudhury\Support\Forge\Api\Client as ApiForge;

class Api extends ApiForge
{

    protected $DEFAULT_API_JSON_PATH = './config/GuzzleDescription.json';
    
    protected $DEFAULTS = [
        'AuthToken' => 'xxxxxxxxxxxxxxxxxxxxxxxxxx',
        'ClientID' => 'xxxxxxxxxxxxxxx',
        'client' => [
            'base_uri' => 'https://api.provider.com/api/v1/',
            'verify' => false,
            'headers' => [
                'Authorization' => 'authtoken {{AuthToken}}',
                'X-clientID' => "{{ClientID}}",
            ],
        ],
    ];

}
 

应该就是这样。没有其他需要。所有API端点都将智能转换为该类的函数。例如,如果您有一个端点[GET]/products,您将获得一个getProducts函数。这里有一些更多示例

尽可能使单复数一致。

可能会出现这种情况,即API端点结构相同,但传递给它的数据决定了完全不同的操作。理想情况下,这种情况不应发生,但并非所有API端点都是理想创建的。因此,像[get]/products?filter_by=active这样的端点以及另一个端点[get]/products将具有相同的名称。为了保留两个端点,默认行为是在重复名称前添加一个_。但是,您可以添加过滤器或钩子,将重复的名称完全更改为其他名称。

安装

要求

  • PHP 7.0+的任何版本都可以

使用Composer安装

您可以通过将以下行添加到composer.json文件中的require块(将dev-master替换为最新稳定版本)来通过Composer安装库:

"sudiptochoudhury/php-api-client-forge": "dev-master"

或运行以下命令

composer require sudiptochoudhury/php-api-client-forge

导入Postman JSON

使用COllecton v2.1格式导出您的Postman集合。它将以JSON格式导出。为文件命名,例如postman.json,并将其保存在项目的文件夹中。

接下来,扩展Import类(推荐)或直接使用。

通过扩展Import

<?php
namespace My\Namespace\ApiProvider;

use SudiptoChoudhury\Support\Forge\Api\Import as ParentImport;

/**
 * Class Import
 *
 * @package Pour\Package\Name
 */
class Import extends ParentImport
{

    protected $DEFAULT_API_JSON_PATH = './config/GuzzleDescription.json';
    protected $DEFAULT_SOURCE_JSON_PATH = './config/postman.json';
    
}

您已经准备好导入。就是这样(尽管有许多可配置选项和钩子……我们很快就会谈到这些)。

现在,让我们将导入到代码库的另一个部分。

<?php

use My\Namespace\ApiProvider\Import;
...
new (Import())->writeDefinition();
...

完成!

直接使用父类

这甚至更简单(尽管如此)

<?php

use SudiptoChoudhury\Support\Forge\Api\Import;

...
new (Import([
   './config/postman.json'
]))->writeDefinition( './config/GuzzleDescription.json');
...

更简单,对吧!

您将找到一个新的.json文件、一个新的.md文件和一个新的.php文件,这些文件将有助于您在API项目中取得成功。

.json文件显然基于创建GuzzleHttp\Command\Guzzle\Description对象所需的数据结构。

.php文件包含phpDoc @method定义,可能看起来像这样

<?php
/** 
 * @method	array	getHostedpage(array $parameters)	Getting the details of a particular hosted page
 * @method	array	getHostedpages()	Listing all the hostedpages

您可以将方法定义部分复制到从Client类扩展的API类中。

.md文件是一个包含API函数详细信息、等效端点、参数、参数的默认值(如果有定义)和描述的Markdown文件——所有这些都是从Postman JSON文件中派生出来的。

然而,我建议您使用扩展选项,因为您将获得大量选项来在将Postman数据转换为Guzzle Description的过程中挂钩到父代码的各个部分。您可能想要添加默认值或更改名称、更改描述或跳过一些项目。所有这些都可以通过覆盖Import父类的函数和定义自定义过滤器函数来完成。

什么是自定义过滤器函数?!!!

好的,让我们举一个例子。假设您看到您想要更改[get]/products的重复函数名称,正如我在上一节中提到的示例。默认情况下,重复名称将被设置为_getProducts(还记得吗?默认情况下,在名称前添加一个_)。

现在,在您的扩展Import类中,只需定义此内容

<?php

		/** This is a filter 
		* @param $apiFunctionName
		* @param array $helperData
	 	* @return string
	 */
    public function filterFinalName($apiFunctionName, $helperData = [])
    {
        if ($apiFunctionName === '_getProducts') {
            $apiFunctionName = 'getActiveProducts';
        }
        return $apiFunctionName;
    }

这是一个过滤器函数。名称必须以filter开头,然后是过滤器名称,然后可以可选地添加一个_和任何您想要的后续内容,以防您想为同一过滤器定义多个函数(如filterFinalName_xxxfilterFinalName_001)。

每个过滤器函数都将接收要修改的第一个参数的值。可选的第二个参数将是一个辅助数据项的关联数组,这些数据项可能有助于确定如何应用过滤器的逻辑。有时它也可能是构建文档布局的数据源。例如,Markdown API表是通过默认过滤器生成的。您可以覆盖它以以自己的方式生成API表。也许您不喜欢表格结构,您可以设计自己的结构。天高任鸟飞。此外,还有很多过滤器专门用于创建完整的Markdown文档,包括标题、菜单、描述、表格、页眉、页脚、安装、甚至捐赠和联系方式。只需点击所需的布局过滤器,并填写您自己的内容。

下表提供了所有过滤器的详细信息。

但在那之前,您也可以通过完全覆盖父类的方法来实现类似的功能。例如,可以通过覆盖 readApiName 方法来扩展或替换现有的逻辑,以检测函数名,并使用您自己的逻辑。然而,过滤器可以帮助您以更细粒度的方式更改事物。您可以为单个要覆盖的函数应用多达10个过滤器,您可能只需要使用其中一个过滤器,而不是编写一大堆覆盖代码。当然,选择权在您手中。