acc-create-psr18-http-client

Generates PSR-18 HTTP Client implementation for PHP 8.5. Creates ClientInterface with request sending and exception handling. Includes unit tests.

16 stars

Best use case

acc-create-psr18-http-client is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Generates PSR-18 HTTP Client implementation for PHP 8.5. Creates ClientInterface with request sending and exception handling. Includes unit tests.

Teams using acc-create-psr18-http-client should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/acc-create-psr18-http-client/SKILL.md --create-dirs "https://raw.githubusercontent.com/diegosouzapw/awesome-omni-skill/main/skills/tools/acc-create-psr18-http-client/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/acc-create-psr18-http-client/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How acc-create-psr18-http-client Compares

Feature / Agentacc-create-psr18-http-clientStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Generates PSR-18 HTTP Client implementation for PHP 8.5. Creates ClientInterface with request sending and exception handling. Includes unit tests.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# PSR-18 HTTP Client Generator

## Overview

Generates PSR-18 compliant HTTP client implementations for external API communication.

## When to Use

- External API integrations
- Microservice communication
- HTTP-based service calls
- Building HTTP client wrappers

## Template: HTTP Client

```php
<?php

declare(strict_types=1);

namespace App\Infrastructure\Http\Client;

use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

final readonly class CurlHttpClient implements ClientInterface
{
    public function __construct(
        private array $options = [],
    ) {
    }

    public function sendRequest(RequestInterface $request): ResponseInterface
    {
        $ch = curl_init();

        try {
            $this->configureCurl($ch, $request);
            $response = curl_exec($ch);

            if ($response === false) {
                throw new NetworkException(
                    $request,
                    curl_error($ch),
                    curl_errno($ch),
                );
            }

            $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
            $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

            $headerString = substr($response, 0, $headerSize);
            $body = substr($response, $headerSize);

            return $this->buildResponse($statusCode, $headerString, $body);
        } finally {
            curl_close($ch);
        }
    }

    private function configureCurl($ch, RequestInterface $request): void
    {
        $options = [
            CURLOPT_URL => (string) $request->getUri(),
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HEADER => true,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_MAXREDIRS => 5,
            CURLOPT_TIMEOUT => $this->options['timeout'] ?? 30,
            CURLOPT_CONNECTTIMEOUT => $this->options['connect_timeout'] ?? 10,
            CURLOPT_CUSTOMREQUEST => $request->getMethod(),
        ];

        // Set headers
        $headers = [];
        foreach ($request->getHeaders() as $name => $values) {
            $headers[] = $name . ': ' . implode(', ', $values);
        }
        $options[CURLOPT_HTTPHEADER] = $headers;

        // Set body
        $body = (string) $request->getBody();
        if ($body !== '') {
            $options[CURLOPT_POSTFIELDS] = $body;
        }

        // SSL options
        if (isset($this->options['verify_ssl']) && !$this->options['verify_ssl']) {
            $options[CURLOPT_SSL_VERIFYPEER] = false;
            $options[CURLOPT_SSL_VERIFYHOST] = 0;
        }

        curl_setopt_array($ch, $options);
    }

    private function buildResponse(int $statusCode, string $headerString, string $body): ResponseInterface
    {
        $headers = $this->parseHeaders($headerString);

        return (new Response($statusCode))
            ->withBody(new Stream($body))
            ->withHeaders($headers);
    }

    private function parseHeaders(string $headerString): array
    {
        $headers = [];
        $lines = explode("\r\n", trim($headerString));

        foreach ($lines as $line) {
            if (str_contains($line, ':')) {
                [$name, $value] = explode(':', $line, 2);
                $headers[trim($name)] = [trim($value)];
            }
        }

        return $headers;
    }
}
```

## Template: Exceptions

```php
<?php

declare(strict_types=1);

namespace App\Infrastructure\Http\Client;

use Psr\Http\Client\ClientExceptionInterface;
use Psr\Http\Client\NetworkExceptionInterface;
use Psr\Http\Client\RequestExceptionInterface;
use Psr\Http\Message\RequestInterface;

final class ClientException extends \RuntimeException implements ClientExceptionInterface
{
}

final class NetworkException extends \RuntimeException implements NetworkExceptionInterface
{
    public function __construct(
        private readonly RequestInterface $request,
        string $message = '',
        int $code = 0,
        ?\Throwable $previous = null,
    ) {
        parent::__construct($message, $code, $previous);
    }

    public function getRequest(): RequestInterface
    {
        return $this->request;
    }
}

final class RequestException extends \RuntimeException implements RequestExceptionInterface
{
    public function __construct(
        private readonly RequestInterface $request,
        string $message = '',
        int $code = 0,
        ?\Throwable $previous = null,
    ) {
        parent::__construct($message, $code, $previous);
    }

    public function getRequest(): RequestInterface
    {
        return $this->request;
    }
}
```

## Template: Logging Client Decorator

```php
<?php

declare(strict_types=1);

namespace App\Infrastructure\Http\Client;

use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Log\LoggerInterface;

final readonly class LoggingHttpClient implements ClientInterface
{
    public function __construct(
        private ClientInterface $client,
        private LoggerInterface $logger,
    ) {
    }

    public function sendRequest(RequestInterface $request): ResponseInterface
    {
        $context = [
            'method' => $request->getMethod(),
            'uri' => (string) $request->getUri(),
        ];

        $this->logger->info('HTTP request starting', $context);

        $startTime = microtime(true);

        try {
            $response = $this->client->sendRequest($request);
            $duration = microtime(true) - $startTime;

            $this->logger->info('HTTP request completed', [
                ...$context,
                'status' => $response->getStatusCode(),
                'duration_ms' => round($duration * 1000, 2),
            ]);

            return $response;
        } catch (\Throwable $e) {
            $this->logger->error('HTTP request failed', [
                ...$context,
                'error' => $e->getMessage(),
            ]);

            throw $e;
        }
    }
}
```

## Usage Example

```php
<?php

use App\Infrastructure\Http\Client\CurlHttpClient;
use App\Infrastructure\Http\Client\LoggingHttpClient;
use App\Infrastructure\Http\Factory\HttpFactory;

$factory = new HttpFactory();
$client = new LoggingHttpClient(
    new CurlHttpClient(['timeout' => 30]),
    $logger,
);

// Send GET request
$request = $factory->createRequest('GET', 'https://api.example.com/users')
    ->withHeader('Authorization', 'Bearer token');

$response = $client->sendRequest($request);
$data = json_decode((string) $response->getBody(), true);

// Send POST request
$request = $factory->createRequest('POST', 'https://api.example.com/users')
    ->withHeader('Content-Type', 'application/json')
    ->withBody($factory->createStream(json_encode(['name' => 'John'])));

$response = $client->sendRequest($request);
```

## Requirements

```json
{
    "require": {
        "psr/http-client": "^1.0",
        "psr/http-message": "^2.0"
    }
}
```

Related Skills

agent-client-protocol

16
from diegosouzapw/awesome-omni-skill

Agent Client Protocol (ACP) - Standardized communication between code editors and AI coding agents. Use for building ACP-compatible agents, integrating agents with editors (Zed, JetBrains, Neovim), implementing tool calls, file operations, and session management.

acc-create-test-builder

16
from diegosouzapw/awesome-omni-skill

Generates Test Data Builder and Object Mother patterns for PHP 8.5. Creates fluent builders with sensible defaults and factory methods for test data creation.

acc-create-query

16
from diegosouzapw/awesome-omni-skill

Generates CQRS Queries and Handlers for PHP 8.5. Creates read-only query DTOs with handlers that return data without side effects. Includes unit tests.

acc-create-psr14-event-dispatcher

16
from diegosouzapw/awesome-omni-skill

Generates PSR-14 Event Dispatcher implementation for PHP 8.5. Creates EventDispatcherInterface, ListenerProviderInterface, and StoppableEventInterface with event propagation. Includes unit tests.

acc-create-entity

16
from diegosouzapw/awesome-omni-skill

Generates DDD Entities for PHP 8.5. Creates identity-based objects with behavior, state transitions, and invariant protection. Includes unit tests.

acc-create-builder

16
from diegosouzapw/awesome-omni-skill

Generates Builder pattern for PHP 8.5. Creates step-by-step object construction with fluent interface and validation. Includes unit tests.

acc-create-value-object

16
from diegosouzapw/awesome-omni-skill

Generates DDD Value Objects for PHP 8.5. Creates immutable, self-validating objects with equality comparison. Includes unit tests.

acc-create-unit-test

16
from diegosouzapw/awesome-omni-skill

Generates PHPUnit unit tests for PHP 8.5. Creates isolated tests with AAA pattern, proper naming, attributes, and one behavior per test. Supports Value Objects, Entities, Services.

acc-create-test-double

16
from diegosouzapw/awesome-omni-skill

Generates test doubles (Mocks, Stubs, Fakes, Spies) for PHP 8.5. Creates appropriate double type based on testing needs with PHPUnit MockBuilder patterns.

acc-create-psr7-http-message

16
from diegosouzapw/awesome-omni-skill

Generates PSR-7 HTTP Message implementations for PHP 8.5. Creates Request, Response, Stream, Uri, and ServerRequest classes with immutability. Includes unit tests.

acc-create-policy

16
from diegosouzapw/awesome-omni-skill

Generates Policy pattern for PHP 8.5. Creates encapsulated business rules for authorization, validation, and domain constraints. Includes unit tests.

acc-create-null-object

16
from diegosouzapw/awesome-omni-skill

Generates Null Object pattern for PHP 8.5. Creates safe default implementations eliminating null checks. Includes unit tests.