定制 jardisadapter/http 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

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

jardisadapter/http

Composer 安装命令:

composer require jardisadapter/http

包简介

PSR-18 HTTP client with cURL transport, Bearer and Basic auth, retry with exponential backoff, and minimal footprint; a building block of the open-source foundation that Jardis-generated DDD code runs on

README 文档

README

Build Status License: MIT PHP Version PHPStan Level PSR-12 PSR-18

Part of Jardis — the Domain-Driven Design platform for PHP. You model your domain; Jardis generates the production-ready hexagonal code (DTOs, Command/Query handlers, repositories, persistence). This package is part of the open-source foundation that generated code runs on.

HTTP requests without overhead. A lean PSR-18 HTTP client for PHP built on cURL — designed for applications that call external APIs, send webhooks, or integrate services. No framework, no middleware stack, no dependency bloat. Just what you need.

Why This Client?

  • Two classes to learnHttpClient + ClientConfig. Includes its own PSR-7/PSR-17 implementation — zero external dependencies
  • Handler pipeline — each concern is its own invokable, orchestrated internally by the client
  • Retry with backoff — automatic retry on 5xx and network errors
  • PSR-18 compatible — works with any PSR-18-capable code
  • 96% test coverage — integration tests against real HTTP requests, not mocks

Installation

composer require jardisadapter/http

Quick Start

GET Request

use JardisAdapter\Http\HttpClient;
use JardisAdapter\Http\Config\ClientConfig;

use JardisAdapter\Http\Message\Psr17Factory;

$psr17 = new Psr17Factory();
$client = new HttpClient($psr17, $psr17, $psr17, $psr17, new ClientConfig(
    baseUrl: 'https://api.example.com/v2',
));

$response = $client->get('/users');
$data = json_decode((string) $response->getBody(), true);

POST with JSON Body

$response = $client->post('/users', [
    'name' => 'John Doe',
    'email' => 'john@example.com',
]);

PUT, PATCH, DELETE

$client->put('/users/1', ['name' => 'Jane Doe']);
$client->patch('/users/1', ['status' => 'active']);
$client->delete('/users/1');

Custom Headers per Request

$response = $client->get('/reports', ['Accept' => 'text/csv']);
$response = $client->post('/import', $data, ['X-Request-Id' => 'abc-123']);

Fully Configured

$psr17 = new Psr17Factory();
$client = new HttpClient($psr17, $psr17, $psr17, $psr17, new ClientConfig(
    baseUrl: 'https://api.example.com/v2',
    timeout: 10,
    connectTimeout: 5,
    verifySsl: true,
    defaultHeaders: ['Accept' => 'application/json'],
    bearerToken: 'eyJhbGciOiJI...',
    maxRetries: 3,
    retryDelayMs: 200,
));

$response = $client->get('/users');
$response = $client->post('/orders', ['product' => 'Widget', 'quantity' => 3]);

Authentication

Bearer Token

$psr17 = new Psr17Factory();
$client = new HttpClient($psr17, $psr17, $psr17, $psr17, new ClientConfig(
    bearerToken: 'eyJhbGciOiJI...',
));
// Authorization: Bearer eyJhbGciOiJI... is set automatically

Basic Auth

$psr17 = new Psr17Factory();
$client = new HttpClient($psr17, $psr17, $psr17, $psr17, new ClientConfig(
    basicUser: 'api-user',
    basicPassword: 'secret',
));

Retry

$psr17 = new Psr17Factory();
$client = new HttpClient($psr17, $psr17, $psr17, $psr17, new ClientConfig(
    maxRetries: 3,          // Up to 3 retries on 5xx
    retryDelayMs: 200,      // Exponential backoff: 200ms, 400ms, 800ms
));

Automatically retries on HTTP 5xx and transport errors (HttpClientException, which covers both NetworkException and RequestException). No retry on 4xx — those are caller errors.

Error Handling

The client does not throw exceptions on HTTP 4xx/5xx — those are valid responses. Exceptions are only thrown for actual errors:

Exception When
NetworkException DNS failure, connection refused, timeout
RequestException Invalid request (malformed URI)
use JardisAdapter\Http\Exception\NetworkException;

try {
    $response = $client->get('/users');
} catch (NetworkException $e) {
    // Network problem — retry was already active (if configured)
}

if ($response->getStatusCode() >= 400) {
    // Handle HTTP errors yourself
}

PSR-18 Compatible

The client implements Psr\Http\Client\ClientInterface. For full control over the request, use sendRequest():

use JardisAdapter\Http\Message\Psr17Factory;

$factory = new Psr17Factory();
$request = $factory->createRequest('OPTIONS', 'https://api.example.com');
$response = $client->sendRequest($request);

Architecture

The user only sees HttpClient + ClientConfig. Internally, the client orchestrates a pipeline of invokable handlers — built from the config:

HttpClient (Orchestrator)
  │
  │  Convenience methods: get(), post(), put(), patch(), delete(), head()
  │  └── internally create PSR-7 requests
  │
  │  Transformers (Request → Request, built from config):
  │  ├── BaseUrl           resolve relative URLs
  │  ├── DefaultHeaders    set default headers
  │  ├── BearerAuth        add bearer token
  │  └── BasicAuth         add basic auth
  │
  │  Transport (Request → Response, built from config):
  │  ├── CurlTransport     cURL-based transport
  │  └── Retry             wraps transport with exponential backoff
  │
  ▼
  sendRequest():
    foreach transformer → $request = $transform($request)
    return $transport($request, $config)

Each handler is an invokable object (__invoke) — independently testable, replaceable, composable. Only what is configured gets instantiated.

Custom Transport

The transport is a closure — replaceable without changing the client:

$psr17 = new Psr17Factory();
$client = new HttpClient(
    requestFactory: $psr17,
    streamFactory: $psr17,
    responseFactory: $psr17,
    uriFactory: $psr17,
    config: new ClientConfig(),
    transport: function (RequestInterface $request, ClientConfig $config) use ($psr17) {
        return $psr17->createResponse(200)
            ->withBody($psr17->createStream('{"mocked": true}'));
    },
);

Jardis Foundation Integration

In a Jardis DDD project, the client is automatically configured via ENV:

HTTP_BASE_URL=https://api.example.com
HTTP_TIMEOUT=30
HTTP_CONNECT_TIMEOUT=10
HTTP_VERIFY_SSL=true
HTTP_BEARER_TOKEN=eyJhbGciOiJI...
HTTP_MAX_RETRIES=3
HTTP_RETRY_DELAY_MS=200

The HttpClientHandler in JardisApp builds the client and registers it in the ServiceRegistry. Your domain code receives ClientInterface via injection — without ever importing HttpClient directly.

Development

cp .env.example .env    # One-time setup
make install             # Install dependencies
make phpunit             # Run tests
make phpstan             # Static analysis (Level 8)
make phpcs               # Coding standards (PSR-12)

Documentation

Full documentation, guides, and API reference:

docs.jardis.io/en/adapter/http

License

MIT License — free for any use, including commercial.

AI-Assisted Development

This package ships with a skill for Claude Code, Cursor, Continue, and Aider. Install it in your consuming project:

composer require --dev jardis/dev-skills

More details: https://docs.jardis.io/en/skills

jardisadapter/http 适用场景与选型建议

jardisadapter/http 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 120 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 04 月 02 日, 在 PHP 生态内属于活跃度较高的组件。

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

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

围绕 jardisadapter/http 我们能提供哪些服务?
定制开发 / 二次开发

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

BUG 修复 & 性能优化

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

项目外包 & 长期维护

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

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

统计信息

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

GitHub 信息

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

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-04-02