rnr1721/le7-api-request

le7 PHP MVC 框架或任何 PSR 项目的 API 客户端

1.1.1 2023-05-27 17:27 UTC

This package is auto-updated.

Last update: 2024-08-27 20:34:57 UTC


README

le7 PHP MVC 框架或任何 PSR 项目的 API 客户端 这是一个简单的 PSR API 客户端实现

API 请求工具

此项目提供了一种简单的工具,用于简单地向 API 发送 HTTP 请求。它包括一个工厂类,用于创建 API 请求工具的实例。

它没有自己的 PSR ClientInterface 实现,您可以使用任何自己的。例如: https://github.com/rnr1721/le7-http-client

它能做什么?

  • 使用任何 API 创建请求,创建 GET、POST、PUT、DELETE 请求
  • 允许从响应中获取 ResponseInterface、数组或对象
  • 内置将 JSON、XML 和 CSV 响应转换为对象或数组的转换器
  • 允许创建从 ResponseInterface 到您的数据的自定义转换器
  • 允许预定义设置以使用 DI 容器运行
  • 使用不同的 httpClient (ClientInterface),在它们之间切换
  • 获取最后请求的数据
  • 使用事件,例如用于记录请求
  • 设置全局头部和每个请求的头部
  • 完全 PSR 兼容

要求

  • PHP 8.0 或更高版本
  • Composer(用于安装依赖项)

安装

  1. 通过 composer 安装
composer require rnr1721/le7-api-request

测试

composer test

用法

在此示例中,我使用 Nyholm PSR 库,但您可以使用任何其他库,例如 Guzzle。您还需要 ClientInterface 实现。我使用此实现: https://github.com/rnr1721/le7-http-client

use Core\Factories\HttpClientFactory;
use Nyholm\Psr7\Factory\Psr17Factory;

// Create PSR factories. Nyholm realisation is a single factory to all
$psr17Factory = new Psr17Factory();

// Create httpClient (PSR ClientInterface implementation)
$httpClient = new HttpClientFactory($psr17Factory);

$factory = new HttpClientFactory(
    $psr17Factory, // UriFactoryInterface
    $psr17Factory, // RequestFactoryInterface
    $psr17Factory, // ResponseFactoryInterface
    $psr17Factory, // StreamFactoryInterface
    $httpClient // ClientInterface implementation
);

$apiRequest = $factory->getApiRequest()

$data = [
    // Request data here
];

$headers = [
    'content-language' => 'ru'
];

// Get ResponseInterface for POST request
$apiRequest->post('https://example.com/api', $data, $headers)->getResponse();

// Get array for GET request
$apiRequest->get('https://example.com/api')->toArray();

// Get object for PUT request
$apiRequest->put('https://example.com/api')->toObject();

// Get ResponseInterface for PUT request
// You can use request() method for any request
$apiRequest->request('PUT','https://example.com/api')->getResponse();

// Get array from response
$apiRequest->request('POST','https://example.com', $data, $headers)->toArray();

// Get object from response
$apiRequest->request('POST', 'https://example.com', $data, $headers)->toObject();

// This will return ResponseInterface of request
$apiRequest->getResponse('POST', 'https://example.com', $data, $headers);

// You can set Uri separately if you need it
$apiRequest->setUri('https://example.com');
$apiRequest->getResponse('POST', null, $data, $headers);
$apiRequest->get();

// Make something

// Get last created request
$apiRequest->getLast()->toArray();

头部

您可以使用全局头部,以及每个请求的头部。您可以在调用它时通过请求方法注入每个请求的头部,或通过 setHeader() & setHeaders() 方法。现在,您将看到如何设置全局头部,它将为所有请求添加

$headers = [
    'My-Great-Header' => 'header_value'
    // Array with headers
]

// Set many headers for all requests in future
$apiRequest->setGlobalHeaders($headers);

// Set one global permanent header
$apiRequest->setGlobalHeader('Content-Language', 'en');

也可以为一次性请求设置头部

$headers = [
    'My-Great-Header' => 'header_value'
    // Array with headers
]

// Set many headers for next request only
$apiRequest->setHeaders($headers);

// Set one header for next request only
$apiRequest->setHeader('Content-Language', 'en');

// Also you can set one-time header in method:
$apiRequest->get('https://example.com', null, $headers);

发送文件使用 multipart/form-data

$data = [
    'name' => 'John Doe',
    'email' => 'john.doe@example.com',
    'file' => new SplFileInfo('/path/to/file.jpg')
];

$apiRequest->setContentType('multipart/form-data');

$response = $apiRequest->post('/upload', $data);

客户端设置

如果您使用的是我的 ClientInterface 实现, https://github.com/rnr1721/le7-http-client 您可以设置一些客户端选项

$apiRequest->setTimeout(5); //default 10
$apiRequest->setMaxRedirects(5); // Default is 3
$apiRequest->setFollowLocation(false); // Default is true 

JSON 和 form-data

您可以创建这些请求的内容类型

  • application/json
  • application/x-www-form-urlencoded
  • multipart/form-data

默认为 json,但您可以切换到 form-data

// This is content type for requests,
// Default is application/json
$apiRequest->setContentType('multipart/form-data')

另一种方法是设置头部。这将自动切换到针模式

转换器

默认情况下,您可以将接收到的 ResponseInterface 转换为数组或对象,如下所示

// Get array from response
$apiRequest->request('POST', 'https://example.com', $data, $headers)->toArray();
// Get array from response
$apiRequest->request('POST', 'https://example.com', $data, $headers)->toObject();

您还可以编写自己的转换器。它必须实现 ResponseConvertorInterface

<?php

namespace Core\Interfaces;

use Psr\Http\Message\ResponseInterface;

interface ResponseConvertorInterface
{

    public function get(?ResponseInterface $response = null): mixed;
}

例如,您可以看到 ResponseArrayConverter 和 ResponseObjectConverter

您还可以在创建 ApiRequest 实例时注入转换器

$factory = new HttpClientFactory(
    $psr17Factory, // UriFactoryInterface
    $psr17Factory, // RequestFactoryInterface
    $psr17Factory, // ResponseFactoryInterface
    $psr17Factory, // StreamFactoryInterface
    $httpClient, // ClientInterface implementation
);

// $convertor is ResponseConvertor instance
$apiRequest = $factory->getApiRequest(null, $convertor);

多个 HTTP 客户端

您可以在不同的场景中使用不同的 ClientInterface。任何客户端都有自己的密钥。当您创建 ApiRequest 实例时,注入的 ClientInterface 的密钥为 'default'。由于某些原因,您可能需要添加 ClientInterface 实例。因此,您可以这样做

// We have created instance
$newHttpClient; // ClientInterface

// Add new ClientInterface and make it active
$apiRequest->addHttpClient('new key', $newHttpClient, true);

// Make our requests

// Switch to default ClientInterface
$apiRequest->setActiveHttpClient('default');

Uri 前缀

您可以通过两种方式设置 Uri 前缀以添加到所有 URL 之前

在创建 ApiRequest 实例时

$factory = new HttpClientFactory(
    $psr17Factory, // UriFactoryInterface
    $psr17Factory, // RequestFactoryInterface
    $psr17Factory, // ResponseFactoryInterface
    $psr17Factory, // StreamFactoryInterface
    $httpClient // ClientInterface implementation
);

// $convertor is ResponseConvertor instance
$apiRequest = $factory->getApiRequest('https://example.com');

// And now you can use it -it will be https://example.com/contacts/get
$result = $apiRequest->setUri('/contacts/get')->get();

当您已经创建了实例

$apiRequest->setUriPrefix('https://example.com');

容器配置

在此示例中,我使用这些组件,但您可以使用任何其他组件

<?php

use Core\Interfaces\ApiRequestInterface;
use Nyholm\Psr7\Factory\Psr17Factory;
use Core\Factories\HttpClientFactory;
use Core\Interfaces\HttpClientFactoryInterface;
use Psr\Http\Client\ClientInterface;
use Psr\Container\ContainerInterface;
use function DI\factory;

return [
    ApiRequestInterface::class => factory(function (ContainerInterface $c) {
        /** @var HttpClientFactoryInterface $factory */
        $factory = $c->get(HttpClientFactoryInterface::class);
        return $factory->getApiRequest('https://example.com/api');
    }),
    HttpClientFactoryInterface::class => factory(function (ContainerInterface $c) {
        /** @var Psr17Factory $psr17factory */
        $psr17factory = $c->get(Psr17Factory::class);
        return new HttpClientFactory(
        $psr17factory, // UriFactoryInterface
        $psr17factory, // RequestFactoryInterface
        $psr17factory, // ResponseFactoryInterface
        $psr17factory  // StreamFactoryInterface
        $c->get(ClientInterface::class) // ClientInterface
        );
    }),
    ClientInterface::class => factory(function (ContainerInterface $c) {
        /** @var Psr17Factory $psr17factory */
        $psr17factory = $c->get(Psr17Factory::class);
        return new \Core\HttpClient\HttpClientCurl($psr17factory);
    })
];

PSR 事件

您可以使用事件 AfterApiRequestEvent 来记录请求或以其他方式使用

use Core\Factories\HttpClientFactory;
use Core\Events\AfterApiRequestEvent;
use Psr\EventDispatcher\EventDispatcherInterface;
use Nyholm\Psr7\Factory\Psr17Factory;

// Create PSR factories. Nyholm realisation is a single factory to all
$psr17Factory = new Psr17Factory();

$factory = new HttpClientFactory(
    $psr17Factory, // UriFactoryInterface
    $psr17Factory, // RequestFactoryInterface
    $psr17Factory, // StreamFactoryInterface
    $httpClient, // ClientInterface implementation if not default
);

$apiRequest = $factory->getApiRequest();

// Register the AfterApiRequestEvent
$eventDispatcher->addListener(AfterApiRequestEvent::class, function (AfterApiRequestEvent $event) {
    // Processing event, for example logging
    $response = $event->getResponse();
    $method = $event->getMethod();
    $uri = $event->getUri();
    $data = $event->getData();
    $headers = $event->getHeaders();

    // log response
    // ...
});

// Send the request and get response
$response = $apiRequest->request('GET', 'https://example.com');