friendship ended with social-app. php is my new best friend
1--- 2title: Overview 3description: An overview of the Fetch HTTP package, its architecture and main components 4--- 5 6# Fetch HTTP Package - Overview 7 8## Introduction 9 10The Fetch HTTP package provides a modern, flexible HTTP client for PHP applications, bringing JavaScript's `fetch` API experience to PHP. It features a fluent interface, extensive configuration options, and robust error handling, making it ideal for consuming APIs and working with web services. 11 12## Key Components 13 14The package is comprised of several main components: 15 16### Client 17 18The `Client` class is a high-level wrapper that: 19 20- Implements PSR-18 ClientInterface for standardized HTTP client behavior 21- Implements PSR-3 LoggerAwareInterface for easy integration with logging systems 22- Provides a simple fetch-style API similar to JavaScript's fetch API 23- Handles error conversion to specific exception types 24 25### ClientHandler 26 27The `ClientHandler` class is a more powerful, configurable implementation that: 28 29- Offers a fluent, chainable API for request building 30- Provides extensive configuration options for request customization 31- Supports both synchronous and asynchronous requests 32- Implements retry logic with exponential backoff 33- Offers promise-based operations for complex async workflows 34 35### Response 36 37The `Response` class extends PSR-7 ResponseInterface and provides: 38 39- Rich methods for working with HTTP responses 40- Status code helpers like `isOk()`, `isNotFound()`, etc. 41- Content type inspection with `hasJsonContent()`, `hasHtmlContent()`, etc. 42- Convenient data access methods like `json()`, `text()`, `array()`, `object()` 43- Array access interface for working with JSON responses 44 45### Enums 46 47Type-safe PHP 8.1 enums for HTTP concepts: 48 49- `Method`: HTTP methods (GET, POST, PUT, etc.) 50- `ContentType`: Content types with helpers like `isJson()`, `isText()` 51- `Status`: HTTP status codes with helpers like `isSuccess()`, `isClientError()` 52 53## Feature Highlights 54 55- **JavaScript-like API**: Familiar syntax for developers coming from JavaScript 56- **PSR Compatibility**: Implements PSR-18 (HTTP Client), PSR-7 (HTTP Messages), and PSR-3 (Logger) 57- **Fluent Interface**: Chain method calls for clean, readable code 58- **Type-Safe Enums**: Modern PHP 8.1 enums for HTTP methods, content types, and status codes 59- **Flexible Authentication**: Support for Bearer tokens, Basic auth, and more 60- **Logging**: Comprehensive request/response logging with sanitization of sensitive data 61- **Retries**: Configurable retry logic with exponential backoff and jitter 62- **Asynchronous Requests**: Promise-based async operations with concurrency control 63- **Content Type Handling**: Simplified handling of JSON, forms, multipart data, etc. 64- **Testing Utilities**: Built-in mock response helpers for testing 65 66## Architecture 67 68``` 69+------------------+ 70| Client | <-- High-level API (PSR-18 compliant) 71+------------------+ 72 | 73 v 74+------------------+ 75| ClientHandler | <-- Core implementation with advanced features 76+------------------+ 77 | 78 +-----------+ 79 | Traits | <-- Functionality separated into focused traits 80 +-----------+ 81 | ConfiguresRequests 82 | HandlesUris 83 | ManagesPromises 84 | ManagesRetries 85 | PerformsHttpRequests 86 +-----------+ 87 | 88 v 89+------------------+ 90| Response | <-- Enhanced response handling 91+------------------+ 92 | 93 v 94+------------------+ 95| Guzzle Client | <-- Underlying HTTP client implementation 96+------------------+ 97``` 98 99## Usage Patterns 100 101### Simple Usage 102 103```php 104// Global helper functions for quick requests 105$response = fetch('https://api.example.com/users'); 106$users = $response->json(); 107 108// HTTP method-specific helpers 109$user = post('https://api.example.com/users', [ 110 'name' => 'John Doe', 111 'email' => 'john@example.com' 112])->json(); 113``` 114 115### Advanced Configuration 116 117The `ClientHandler` class offers more control and customization options for advanced use cases: 118 119```php 120use Fetch\Http\ClientHandler; 121 122$handler = new ClientHandler(); 123$response = $handler 124 ->withToken('your-api-token') 125 ->withHeaders(['Accept' => 'application/json']) 126 ->withQueryParameters(['page' => 1, 'limit' => 10]) 127 ->timeout(5) 128 ->retry(3, 100) 129 ->get('https://api.example.com/users'); 130``` 131 132### Type-Safe Enums 133 134```php 135use Fetch\Enum\Method; 136use Fetch\Enum\ContentType; 137use Fetch\Enum\Status; 138 139// Use enums for HTTP methods 140$client = fetch_client(); 141$response = $client->request(Method::POST, '/users', $userData); 142 143// Check HTTP status with enums 144if ($response->statusEnum() === Status::OK) { 145 // Process successful response 146} 147 148// Content type handling 149$response = $client->withBody($data, ContentType::JSON)->post('/users'); 150``` 151 152### Asynchronous Requests 153 154For handling multiple requests efficiently: 155 156```php 157use function async; 158use function await; 159use function all; 160 161// Execute an async function 162await(async(function() { 163 // Create multiple requests 164 $results = await(all([ 165 'users' => async(fn() => fetch('https://api.example.com/users')), 166 'posts' => async(fn() => fetch('https://api.example.com/posts')), 167 'comments' => async(fn() => fetch('https://api.example.com/comments')) 168 ])); 169 170 // Process the results 171 $users = $results['users']->json(); 172 $posts = $results['posts']->json(); 173 $comments = $results['comments']->json(); 174 175 echo "Fetched " . count($users) . " users, " . 176 count($posts) . " posts, and " . 177 count($comments) . " comments"; 178})); 179``` 180 181### Global Client Configuration 182 183```php 184// Configure once at application bootstrap 185fetch_client([ 186 'base_uri' => 'https://api.example.com', 187 'headers' => [ 188 'User-Agent' => 'MyApp/1.0', 189 'Accept' => 'application/json', 190 ], 191 'timeout' => 10, 192]); 193 194// Use the configured client throughout your application 195function getUserData($userId) { 196 return fetch_client()->get("/users/{$userId}")->json(); 197} 198 199function createUser($userData) { 200 return fetch_client()->post('/users', $userData)->json(); 201} 202``` 203 204## Enhanced Response Handling 205 206```php 207$response = fetch('https://api.example.com/users/1'); 208 209// Status code helpers 210if ($response->isOk()) { 211 // Handle 200 OK 212} else if ($response->isNotFound()) { 213 // Handle 404 Not Found 214} else if ($response->isUnauthorized()) { 215 // Handle 401 Unauthorized 216} 217 218// Status category helpers 219if ($response->successful()) { 220 // Handle any 2xx status 221} else if ($response->isClientError()) { 222 // Handle any 4xx status 223} else if ($response->isServerError()) { 224 // Handle any 5xx status 225} 226 227// Content type helpers 228if ($response->hasJsonContent()) { 229 $data = $response->json(); 230} else if ($response->hasHtmlContent()) { 231 $html = $response->text(); 232} 233 234// Array access for JSON responses 235$user = $response['user']; 236$name = $response['user']['name']; 237``` 238 239## When to Use Each Class 240 241### Use `Client` when 242 243- You need PSR-18 compatibility 244- You prefer a simpler API similar to JavaScript's fetch 245- You're working within a framework that expects a PSR-18 client 246- You want built-in exception handling for network and HTTP errors 247 248### Use `ClientHandler` when 249 250- You need advanced configuration options 251- You want to use asynchronous requests and promises 252- You need fine-grained control over retries and timeouts 253- You're performing complex operations like concurrent requests 254 255### Use global helpers (`fetch()`, `get()`, `post()`, etc.) when 256 257- You're making simple, one-off requests 258- You don't need extensive configuration 259- You want the most concise, readable code 260 261## Exception Handling 262 263The package provides several exception types for different error scenarios: 264 265- `NetworkException`: For connection and network-related errors 266- `RequestException`: For HTTP request errors 267- `ClientException`: For unexpected client errors 268- `TimeoutException`: For request timeouts 269 270Each exception provides context about the failed request to aid in debugging and error handling.