Skip to content

utopia-php/client

Repository files navigation

Utopia Client

A small PSR-18 HTTP client for PHP 8.4+. cURL and Swoole coroutine transports, PSR-7 messages, and request/response helpers for JSON, XML, text, forms, and multipart.

Install

composer require utopia-php/client

Use ext-curl for the cURL adapter and ext-swoole for the Swoole coroutine adapter.

Quick Start

<?php

use Utopia\Client;
use Utopia\Client\Adapter\Curl\Client as CurlAdapter;
use Utopia\Psr7\Method;
use Utopia\Psr7\Request;

require __DIR__ . '/vendor/autoload.php';

$client = new Client(new CurlAdapter());
$requestFactory = new Request\Factory();

$request = $requestFactory->json(Method::POST, 'https://example.com/users', [
    'name' => 'Ada',
]);

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

echo $response->getStatusCode();
echo $response->json()['name'];

Utopia\Client implements Psr\Http\Client\ClientInterface, so it works anywhere a PSR-18 client is expected. HTTP/1.1 is used by default and redirects are not followed, so you receive exactly the response the server returned.

Configure the client

Defaults are immutable — each with*() returns a configured clone, and a default never overrides a header already set on the request.

<?php

use Utopia\Psr7\ContentType;
use Utopia\Psr7\Header;

$client = $client
    ->withBaseUri('https://api.example.com/v1')   // relative request URIs resolve against this
    ->withHeaders([
        Header::ACCEPT => ContentType::JSON,
        Header::USER_AGENT => 'Acme API Client',
    ])
    ->withBearerAuth('token');                     // or ->withBasicAuth('user', 'pass')

Build requests

<?php

use Utopia\Psr7\Method;
use Utopia\Psr7\Request;
use Utopia\Psr7\Request\Multipart\Part;

$requestFactory = new Request\Factory();

$json = $requestFactory->json(Method::POST, 'https://api.example.com/users', [
    'name' => 'Ada',
]);

$form = $requestFactory->form(Method::POST, 'https://api.example.com/sessions', [
    'email' => 'ada@example.com',
    'password' => 'secret',
]);

$query = $requestFactory->query(Method::GET, 'https://api.example.com/users', [
    'page' => 2,
    'search' => 'Ada Lovelace',
]);

$upload = $requestFactory->multipart(Method::POST, 'https://api.example.com/uploads', [
    'name' => 'Ada',
    'avatar' => Part::file('avatar', '/tmp/avatar.png', 'avatar.png', 'image/png'),
]);

$xml = $requestFactory->xml(Method::POST, 'https://api.example.com/users', '<user><name>Ada</name></user>');

$text = $requestFactory->text(Method::POST, 'https://api.example.com/notes', 'Hello, Ada');

Pass a 4th $headers array to any factory method to override defaults, such as a custom Content-Type or Accept.

Decode responses

<?php

$type = $response->contentType(); // media type without parameters, e.g. "application/json"
$data = $response->json();
$xml = $response->xml();
$text = $response->text();
$form = $response->form();
$parts = $response->multipart();

foreach ($parts as $part) {
    $name = $part->name();
    $filename = $part->filename();
    $contentType = $part->contentType();
    $body = $part->body();
}

HTTP 4xx and 5xx responses are returned, not thrown, as required by PSR-18.

More

  • Streaming — consume large downloads (SSE, LLM token streams) and upload large files, both with bounded memory.
  • Retries — the Retry decorator and its configurable best-practice backoff strategy.
  • Configuration — timeouts, TLS, native cURL options, and the Swoole coroutine adapter.
  • Error handling — the PSR-18 exception hierarchy the adapters throw.
  • Development — running the test suite and checks.

About

WIP

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages