rnr1721/le7-api-request 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

rnr1721/le7-api-request

Composer 安装命令:

composer require rnr1721/le7-api-request

包简介

API client for le7 PHP MVC framework or any PSR project

README 文档

README

API client for le7 PHP MVC framework or any PSR project This is an simple PSR API client implementation

API Request Utility

This project provides a simple utility for simple making HTTP requests to an API. It includes a factory class for creating instances of the API request utility.

It not have own PSR ClientInterface implementation, and you can use any own. For example: https://github.com/rnr1721/le7-http-client

What it can?

  • Create requests using any API, creating GET, POST, PUT, DELETE requests
  • Allow to get ResponseInterface, array or object from response
  • Built-in converters of JSON, XML and CSV responses to object or array
  • Allow to create own convertors from ResponseInterface to your data
  • Allow pre-define settings for run using DI containers
  • Using different httpClients (ClientInterface), swithcing between them
  • Get last request data
  • Using events, for example for logging requests
  • Set global headers and headers per-request
  • Full PSR compatible

Requirements

  • PHP 8.0 or higher
  • Composer (for installing dependencies)

Installation

  1. Install via composer:
composer require rnr1721/le7-api-request

Testing

composer test

Usage

In this example, I use Nyholm PSR library, but you can use any, Guzzle for example. Also, you will need the ClientInterface implementation. I use this implementation: 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();

Headers

You can use global headers, and headers for each request. Headers for each request you can inject in request methods when you call it or by setHeader() & setHeaders() methods. Now, you will see how setup global headers, that will be added for all requests:

$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');

Also for one-time request headers:

$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);

Sending files with 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);

Client setup

If you are using my implementation of ClientInterface, https://github.com/rnr1721/le7-http-client you can setup some options of client:

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

JSON and form-data

You can create these content-types of requests:

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

By default is json, but you can switch to form-data:

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

Another way is set header. It turn needle mode automatically

Convertors

By default, you can convert recieved ResponseInterface to array or object like this:

// 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();

Also, you can write own convertor. It must implement ResponseConvertorInterface:

<?php

namespace Core\Interfaces;

use Psr\Http\Message\ResponseInterface;

interface ResponseConvertorInterface
{

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

As examples you can see ResponseArrayConverter and ResponseObjectConverter

Also, you can inject convertor when create ApiRequest instance:

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

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

Multiple HTTP clients

You can use different ClientInterface in different situations. Any client have own key. When you create instance of ApiRequest, ClientInterface that you inject have key 'default'. For some reasons you may need add ClientInterface instance. So, you can make this:

// 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 prefixes

You can set the Uri prefix to add before all url in two way

When creating ApiRequest instance:

$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();

When you have already created instance

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

Container configuration

In this example I using these components, but you can use any others:

<?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 Events

You can log requests or somehow else use event 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');

rnr1721/le7-api-request 适用场景与选型建议

rnr1721/le7-api-request 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 31 次下载、GitHub Stars 达 0, 最近一次更新时间为 2023 年 05 月 22 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「framework」 「request」 「component」 「le7」 「le7-framework」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 rnr1721/le7-api-request 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 rnr1721/le7-api-request 我们能提供哪些服务?
定制开发 / 二次开发

基于 rnr1721/le7-api-request 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 31
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 12
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2023-05-22