### GetResource Operation with Error Handling Source: https://context7.com/guzzle/guzzle-services/llms.txt This example demonstrates how to define an API operation 'GetResource' with path parameters and custom error response handling. It shows how to map specific HTTP status codes and phrases to custom exception classes, allowing for more granular error management. ```APIDOC ## GET /resources/{id} ### Description Retrieves a resource identified by its ID. This operation supports custom error handling for specific HTTP status codes. ### Method GET ### Endpoint /resources/{id} ### Parameters #### Path Parameters - **id** (string) - Required - The unique identifier of the resource. #### Error Responses - **404** - Maps to `NotFoundException`. - **429** - Maps to `RateLimitException`. - **503 Service Unavailable** - Maps to `CommandException`. ``` -------------------------------- ### Using ValidatedDescriptionHandler for Parameter Validation Source: https://context7.com/guzzle/guzzle-services/llms.txt This snippet demonstrates how to configure and use the ValidatedDescriptionHandler middleware. It defines a service description with parameters and then creates a GuzzleClient with validation enabled. The example shows how invalid parameters trigger a CommandException with detailed error messages. ```php use GuzzleHttp\Client; use GuzzleHttp\Command\Guzzle\Description; use GuzzleHttp\Command\Guzzle\GuzzleClient; use GuzzleHttp\Command\Exception\CommandException; $description = new Description([ 'baseUri' => 'https://api.example.com', 'operations' => [ 'Register' => [ 'httpMethod' => 'POST', 'uri' => '/register', 'responseModel' => 'UserResult', 'parameters' => [ 'username' => [ 'type' => 'string', 'location' => 'json', 'required' => true, 'minLength' => 3, 'maxLength' => 30, 'pattern' => '/^[a-z0-9_]+$/', ], 'password' => [ 'type' => 'string', 'location' => 'json', 'required' => true, 'minLength' => 8, ], 'age' => [ 'type' => 'integer', 'location' => 'json', 'minimum' => 18, ], ], ], ], 'models' => ['UserResult' => ['type' => 'object', 'additionalProperties' => ['location' => 'json']]], ]); // validate => true is the default; set to false to skip validation $client = new GuzzleClient(new Client(), $description, null, null, null, ['validate' => true]); try { $client->Register([ 'username' => 'AB', // too short and uppercase 'password' => 'short', // too short 'age' => 16, // below minimum ]); } catch (CommandException $e) { echo $e->getMessage(); // Validation errors: // [username] length must be greater than or equal to 3 // [username] must match the following regular expression: /^[a-z0-9_]+$/ // [password] length must be greater than or equal to 8 // [age] must be greater than or equal to 18 } ``` -------------------------------- ### Define Operation Parameters with Validation and Filters Source: https://context7.com/guzzle/guzzle-services/llms.txt Define parameters for an operation, specifying types, locations, validation rules (minLength, maxLength, enum, format, minItems, maxItems), and filters for data transformation before serialization. This example demonstrates creating an event with various parameter constraints. ```php use GuzzleHttp\Command\Guzzle\Description; $description = new Description([ 'baseUri' => 'https://api.example.com', 'operations' => [ 'CreateEvent' => [ 'httpMethod' => 'POST', 'uri' => '/events', 'responseModel' => 'Event', 'parameters' => [ 'title' => [ 'type' => 'string', 'location' => 'json', 'required' => true, 'minLength' => 3, 'maxLength' => 200, ], 'category' => [ 'type' => 'string', 'location' => 'json', 'enum' => ['conference', 'webinar', 'workshop'], ], 'start_date' => [ 'type' => 'string', 'location' => 'json', 'format' => 'date-time', // auto-formatted as ISO 8601 ], 'tags' => [ 'type' => 'array', 'location' => 'json', 'minItems' => 1, 'maxItems' => 10, 'items' => ['type' => 'string'], ], 'slug' => [ 'type' => 'string', 'location' => 'json', 'filters' => ['strtolower'], // applied before serialization 'pattern' => '/^[a-z0-9-]+$/', ], ], ], ], 'models' => [ 'Event' => ['type' => 'object', 'additionalProperties' => ['location' => 'json']], ], ]); use GuzzleHttp\Client; use GuzzleHttp\Command\Guzzle\GuzzleClient; use GuzzleHttp\Command\Exception\CommandException; $client = new GuzzleClient(new Client(), $description); try { $event = $client->CreateEvent([ 'title' => 'PHP Conference 2025', 'category' => 'conference', 'start_date' => new \DateTime('2025-06-15 09:00:00'), // formatted to ISO 8601 'tags' => ['php', 'guzzle', 'api'], 'slug' => 'PHP-Conference-2025', // 'strtolower' filter → 'php-conference-2025' ]); echo $event['id']; // 55 } catch (CommandException $e) { // e.g. "[title] length must be greater than or equal to 3" echo $e->getMessage(); } ``` -------------------------------- ### CreateEvent Operation Source: https://context7.com/guzzle/guzzle-services/llms.txt Defines the 'CreateEvent' operation with parameters for title, category, start date, tags, and slug. Includes type constraints, validation rules, and filters. ```APIDOC ## POST /events ### Description Creates a new event with the provided details. This operation supports parameters for title, category, start date, tags, and a slug. ### Method POST ### Endpoint /events ### Parameters #### Request Body - **title** (string) - Required - The title of the event. Must be between 3 and 200 characters. - **category** (string) - Optional - The category of the event. Must be one of: 'conference', 'webinar', 'workshop'. - **start_date** (string) - Optional - The start date and time of the event, formatted as ISO 8601. - **tags** (array) - Optional - A list of tags for the event. Must contain between 1 and 10 string items. - **slug** (string) - Optional - A URL-friendly identifier for the event. Must match the pattern '^[a-z0-9-]+$' and will be converted to lowercase. ### Request Example ```json { "title": "PHP Conference 2025", "category": "conference", "start_date": "2025-06-15T09:00:00+00:00", "tags": ["php", "guzzle", "api"], "slug": "php-conference-2025" } ``` ### Response #### Success Response (200) - **id** (integer) - The unique identifier of the created event. ``` -------------------------------- ### Custom Response Data Extraction with Deserializer Source: https://context7.com/guzzle/guzzle-services/llms.txt Customize how response data is mapped to a Result object by injecting custom response location visitors. This example shows how to extract data from both response headers and the JSON body. ```php use GuzzleHttp\Client; use GuzzleHttp\Command\Guzzle\Description; use GuzzleHttp\Command\Guzzle\GuzzleClient; use GuzzleHttp\Command\Guzzle\Deserializer; use GuzzleHttp\Command\Guzzle\ResponseLocation\HeaderLocation; use GuzzleHttp\Command\Guzzle\ResponseLocation\JsonLocation; $description = new Description([ 'baseUri' => 'https://api.example.com', 'operations' => [ 'GetRateLimit' => [ 'httpMethod' => 'GET', 'uri' => '/rate-limit', 'responseModel' => 'RateLimitResult', ], ], 'models' => [ 'RateLimitResult' => [ 'type' => 'object', 'properties' => [ // Pulled from response header 'x_ratelimit_limit' => [ 'location' => 'header', 'sentAs' => 'X-RateLimit-Limit', 'type' => 'integer', ], // Pulled from response header 'x_ratelimit_remaining' => [ 'location' => 'header', 'sentAs' => 'X-RateLimit-Remaining', 'type' => 'integer', ], // Pulled from JSON body 'reset_at' => ['location' => 'json', 'type' => 'string'], ], ], ], ]); $deserializer = new Deserializer($description, true, [ 'header' => new HeaderLocation('header'), 'json' => new JsonLocation('json'), ]); $client = new GuzzleClient(new Client(), $description, null, $deserializer); $result = $client->GetRateLimit(); echo $result['x_ratelimit_limit']; // 1000 echo $result['x_ratelimit_remaining']; // 842 echo $result['reset_at']; // "2025-01-15T12:00:00Z" ``` -------------------------------- ### Custom Query Parameter Serialization with Serializer Source: https://context7.com/guzzle/guzzle-services/llms.txt Override default query parameter serialization by providing a custom QueryLocation with a specific QuerySerializer. This example demonstrates how to change the format of array parameters in the query string. ```php use GuzzleHttp\Client; use GuzzleHttp\Command\Guzzle\Description; use GuzzleHttp\Command\Guzzle\GuzzleClient; use GuzzleHttp\Command\Guzzle\Serializer; use GuzzleHttp\Command\Guzzle\RequestLocation\QueryLocation; use GuzzleHttp\Command\Guzzle\QuerySerializer\Rfc3986Serializer; $description = new Description([ 'baseUri' => 'https://api.example.com', 'operations' => [ 'Search' => [ 'httpMethod' => 'GET', 'uri' => '/search', 'responseModel' => 'SearchResult', 'parameters' => [ 'tags' => ['type' => 'array', 'location' => 'query'], ], ], ], 'models' => [ 'SearchResult' => ['type' => 'object', 'additionalProperties' => ['location' => 'json']], ], ]); // Default behavior: tags[0]=php&tags[1]=api // With removeNumericIndices=true: tags[]=php&tags[]=api $queryLocation = new QueryLocation('query', new Rfc3986Serializer(true)); $serializer = new Serializer($description, ['query' => $queryLocation]); $client = new GuzzleClient(new Client(), $description, $serializer); $results = $client->Search(['tags' => ['php', 'api', 'rest']]); // Dispatches: GET https://api.example.com/search?tags[]=php&tags[]=api&tags[]=rest ``` -------------------------------- ### Serializer - Custom Request Location Override Source: https://context7.com/guzzle/guzzle-services/llms.txt The Serializer converts a Command into a PSR-7 Request. It can be instantiated with custom or overridden request locations, for example to change how query parameters are serialized. ```APIDOC ## `Serializer` — Custom Request Location Override `Serializer` converts a `Command` into a PSR-7 `Request`. It can be instantiated with custom or overridden request locations, for example to change how query parameters are serialized. ```php use GuzzleHttp\Client; use GuzzleHttp\Command\Guzzle\Description; use GuzzleHttp\Command\Guzzle\GuzzleClient; use GuzzleHttp\Command\Guzzle\Serializer; use GuzzleHttp\Command\Guzzle\RequestLocation\QueryLocation; use GuzzleHttp\Command\Guzzle\QuerySerializer\Rfc3986Serializer; $description = new Description([ 'baseUri' => 'https://api.example.com', 'operations' => [ 'Search' => [ 'httpMethod' => 'GET', 'uri' => '/search', 'responseModel' => 'SearchResult', 'parameters' => [ 'tags' => ['type' => 'array', 'location' => 'query'], ], ], ], 'models' => [ 'SearchResult' => ['type' => 'object', 'additionalProperties' => ['location' => 'json']], ], ]); // Default behavior: tags[0]=php&tags[1]=api // With removeNumericIndices=true: tags[]=php&tags[]=api $queryLocation = new QueryLocation('query', new Rfc3986Serializer(true)); $serializer = new Serializer($description, ['query' => $queryLocation]); $client = new GuzzleClient(new Client(), $description, $serializer); $results = $client->Search(['tags' => ['php', 'api', 'rest']]); // Dispatches: GET https://api.example.com/search?tags[]=php&tags[]=api&tags[]=rest ``` ``` -------------------------------- ### Define and Use a Guzzle Service Client Source: https://github.com/guzzle/guzzle-services/blob/1.4/README.md Demonstrates how to create a Guzzle client and a service description to interact with a web service. This includes defining operations, parameters, and response models. ```php use GuzzleHttp\Client; use GuzzleHttp\Command\Guzzle\GuzzleClient; use GuzzleHttp\Command\Guzzle\Description; $client = new Client(); $description = new Description([ 'baseUri' => 'http://httpbin.org/', 'operations' => [ 'testing' => [ 'httpMethod' => 'GET', 'uri' => '/get{?foo}', 'responseModel' => 'getResponse', 'parameters' => [ 'foo' => [ 'type' => 'string', 'location' => 'uri' ], 'bar' => [ 'type' => 'string', 'location' => 'query' ] ] ] ], 'models' => [ 'getResponse' => [ 'type' => 'object', 'additionalProperties' => [ 'location' => 'json' ] ] ] ]); $guzzleClient = new GuzzleClient($client, $description); $result = $guzzleClient->testing(['foo' => 'bar']); echo $result['args']['foo']; // bar ``` -------------------------------- ### GuzzleClient with Default Parameters Source: https://context7.com/guzzle/guzzle-services/llms.txt Illustrates how to configure `GuzzleClient` with default parameters, such as API keys, that are automatically merged into every command, simplifying requests that require consistent parameters. ```APIDOC ## `GuzzleClient` with Default Parameters A `defaults` configuration key merges parameters into every command, useful for API keys or authentication tokens that must accompany every request. ```php use GuzzleHttp\Client; use GuzzleHttp\Command\Guzzle\GuzzleClient; use GuzzleHttp\Command\Guzzle\Description; $description = new Description([ 'baseUri' => 'https://api.example.com', 'operations' => [ 'Search' => [ 'httpMethod' => 'GET', 'uri' => '/search{?q,api_key}', 'parameters' => [ 'q' => ['type' => 'string', 'location' => 'uri', 'required' => true], 'api_key' => ['type' => 'string', 'location' => 'uri', 'required' => true], ], 'responseModel' => 'SearchResult', ], ], 'models' => [ 'SearchResult' => ['type' => 'object', 'additionalProperties' => ['location' => 'json']], ], ]); $client = new GuzzleClient(new Client(), $description, null, null, null, [ 'defaults' => ['api_key' => 'my-secret-key'], ]); // 'api_key' is merged automatically — no need to pass it every call $results = $client->Search(['q' => 'guzzle']); // Dispatches: GET https://api.example.com/search?q=guzzle&api_key=my-secret-key ``` ``` -------------------------------- ### Execute Commands with GuzzleClient Source: https://context7.com/guzzle/guzzle-services/llms.txt Demonstrates how to use GuzzleClient to execute API operations like listing users, retrieving a single user, and creating a new user. It also shows how to disable validation and process raw responses. ```APIDOC ## `GuzzleClient` — Execute Commands `GuzzleClient` wraps a standard Guzzle `Client` with the description layer. Each operation defined in the `Description` becomes a callable magic method. Input is validated against the schema before the request is dispatched; the response is automatically deserialized into a `Result` object. ```php use GuzzleHttp\Client; use GuzzleHttp\Command\Guzzle\GuzzleClient; use GuzzleHttp\Command\Exception\CommandException; $httpClient = new Client(['http_errors' => true]); $guzzleClient = new GuzzleClient($httpClient, $description); // --- GET with URI template variables --- $users = $guzzleClient->ListUsers(['status' => 'active', 'page' => 2, 'per_page' => 25]); // Dispatches: GET https://api.example.com/v1/users?status=active&page=2&per_page=25 foreach ($users['data'] as $user) { echo $user['name'] . PHP_EOL; } // --- GET with a path parameter --- $user = $guzzleClient->GetUser(['id' => '42']); echo $user['name']; // "Jane Doe" echo $user['email']; // "jane@example.com" // --- POST with a JSON body --- try { $newUser = $guzzleClient->CreateUser([ 'name' => 'Bob Smith', 'email' => 'bob@example.com', 'role' => 'admin', ]); echo $newUser['id']; // 99 } catch (CommandException $e) { // Thrown on HTTP error or validation failure echo $e->getMessage(); } // --- Disable validation and raw-response processing --- $rawClient = new GuzzleClient($httpClient, $description, null, null, null, [ 'validate' => false, 'process' => false, // returns raw Psr7\Response ]); $response = $rawClient->GetUser(['id' => '1']); echo $response->getStatusCode(); // 200 echo $response->getBody(); // {"id":1,"name":"Alice",...} ``` ``` -------------------------------- ### Operation Inheritance with `extends` Source: https://context7.com/guzzle/guzzle-services/llms.txt Demonstrates how an operation can inherit properties from a base operation using the 'extends' key, allowing for overrides and additions. This reduces duplication in service descriptions. ```php use GuzzleHttp\Command\Guzzle\Description; $description = new Description([ 'baseUri' => 'https://api.example.com', 'operations' => [ 'BaseListOp' => [ 'httpMethod' => 'GET', 'uri' => '/items{?page,per_page}', 'parameters' => [ 'page' => ['type' => 'integer', 'location' => 'query', 'default' => 1], 'per_page' => ['type' => 'integer', 'location' => 'query', 'default' => 20], ], 'responseModel' => 'ItemList', ], 'ListActiveItems' => [ 'extends' => 'BaseListOp', // inherits httpMethod, uri, per_page, page 'parameters' => [ 'status' => ['type' => 'string', 'location' => 'query', 'default' => 'active', 'static' => true], ], ], ], 'models' => [ 'ItemList' => ['type' => 'object', 'additionalProperties' => ['location' => 'json']], ], ]); $activeOp = $description->getOperation('ListActiveItems'); // Inherited parameter still accessible var_dump($activeOp->hasParam('page')); // bool(true) var_dump($activeOp->hasParam('status')); // bool(true) // Static value can't be overridden by callers var_dump($activeOp->getParam('status')->isStatic()); // bool(true) ``` -------------------------------- ### Build a Command Without Executing Source: https://context7.com/guzzle/guzzle-services/llms.txt Explains how to use `GuzzleClient::getCommand()` to create a `CommandInterface` object for an operation without immediately sending an HTTP request, allowing for inspection or deferred execution. ```APIDOC ## `GuzzleClient::getCommand()` — Build a Command Without Executing `getCommand()` creates a `CommandInterface` object representing an operation call, allowing inspection or deferred execution without immediately sending an HTTP request. ```php use GuzzleHttp\Client; use GuzzleHttp\Command\Guzzle\GuzzleClient; $httpClient = new Client(); $guzzleClient = new GuzzleClient($httpClient, $description); // Build the command (no HTTP request yet) $command = $guzzleClient->getCommand('CreateUser', [ 'name' => 'Alice', 'email' => 'alice@example.com', ]); var_dump($command->getName()); // string(10) "CreateUser" var_dump($command['name']); // string(5) "Alice" // Execute later $result = $guzzleClient->execute($command); echo $result['id']; // 101 ``` ``` -------------------------------- ### GuzzleClient with Default Parameters Source: https://context7.com/guzzle/guzzle-services/llms.txt Configure default parameters for a GuzzleClient to be merged into every command, such as API keys or authentication tokens. ```php use GuzzleHttp\Client; use GuzzleHttp\Command\Guzzle\GuzzleClient; use GuzzleHttp\Command\Guzzle\Description; $description = new Description([ 'baseUri' => 'https://api.example.com', 'operations' => [ 'Search' => [ 'httpMethod' => 'GET', 'uri' => '/search{?q,api_key}', 'parameters' => [ 'q' => ['type' => 'string', 'location' => 'uri', 'required' => true], 'api_key' => ['type' => 'string', 'location' => 'uri', 'required' => true], ], 'responseModel' => 'SearchResult', ], ], 'models' => [ 'SearchResult' => ['type' => 'object', 'additionalProperties' => ['location' => 'json']], ], ]); $client = new GuzzleClient(new Client(), $description, null, null, null, [ 'defaults' => ['api_key' => 'my-secret-key'], ]); // 'api_key' is merged automatically — no need to pass it every call $results = $client->Search(['q' => 'guzzle']); // Dispatches: GET https://api.example.com/search?q=guzzle&api_key=my-secret-key ``` -------------------------------- ### Describe an API Action with Operation Source: https://context7.com/guzzle/guzzle-services/llms.txt Defines an API operation, including HTTP method, URI, parameters, and error responses. Requires the GuzzleHttp\Command\Guzzle\Description class. ```php use GuzzleHttp\Command\Guzzle\Description; $description = new Description([ 'baseUri' => 'https://api.example.com', 'operations' => [ 'DeleteItem' => [ 'httpMethod' => 'DELETE', 'uri' => '/items/{id}', 'summary' => 'Permanently delete an item', 'deprecated' => false, 'responseModel' => 'EmptyResponse', 'parameters' => [ 'id' => ['type' => 'string', 'location' => 'uri', 'required' => true], ], 'errorResponses' => [ ['code' => 404, 'phrase' => 'Not Found', 'class' => 'GuzzleHttp\Command\Exception\CommandException'], ['code' => 403, 'class' => 'GuzzleHttp\Command\Exception\CommandException'], ], ], ], 'models' => [ 'EmptyResponse' => ['type' => 'object'], ], ]); $op = $description->getOperation('DeleteItem'); echo $op->getName(); // DeleteItem echo $op->getHttpMethod(); // DELETE echo $op->getUri(); // /items/{id} echo $op->getSummary(); // Permanently delete an item var_dump($op->getDeprecated()); // bool(false) $idParam = $op->getParam('id'); var_dump($idParam->isRequired()); // bool(true) var_dump($idParam->getType()); // string(6) "string" var_dump($idParam->getLocation()); // string(3) "uri" $errors = $op->getErrorResponses(); echo $errors[0]['code']; // 404 echo $errors[0]['phrase']; // Not Found ``` -------------------------------- ### Build a Command Without Executing Source: https://context7.com/guzzle/guzzle-services/llms.txt Use `GuzzleClient::getCommand()` to create a `CommandInterface` object without sending an HTTP request. This allows for inspection or deferred execution. ```php use GuzzleHttp\Client; use GuzzleHttp\Command\Guzzle\GuzzleClient; $httpClient = new Client(); $guzzleClient = new GuzzleClient($httpClient, $description); // Build the command (no HTTP request yet) $command = $guzzleClient->getCommand('CreateUser', [ 'name' => 'Alice', 'email' => 'alice@example.com', ]); var_dump($command->getName()); // string(10) "CreateUser" var_dump($command['name']); // string(5) "Alice" // Execute later $result = $guzzleClient->execute($command); echo $result['id']; // 101 ``` -------------------------------- ### Execute Commands with GuzzleClient Source: https://context7.com/guzzle/guzzle-services/llms.txt Use GuzzleClient to execute API operations defined in a description. Input is validated, and responses are deserialized. Options like 'validate' and 'process' can control behavior. ```php use GuzzleHttp\Client; use GuzzleHttp\Command\Guzzle\GuzzleClient; use GuzzleHttp\Command\Exception\CommandException; $httpClient = new Client(['http_errors' => true]); $guzzleClient = new GuzzleClient($httpClient, $description); // --- GET with URI template variables --- $users = $guzzleClient->ListUsers(['status' => 'active', 'page' => 2, 'per_page' => 25]); // Dispatches: GET https://api.example.com/v1/users?status=active&page=2&per_page=25 foreach ($users['data'] as $user) { echo $user['name'] . PHP_EOL; } // --- GET with a path parameter --- $user = $guzzleClient->GetUser(['id' => '42']); echo $user['name']; // "Jane Doe" echo $user['email']; // "jane@example.com" // --- POST with a JSON body --- try { $newUser = $guzzleClient->CreateUser([ 'name' => 'Bob Smith', 'email' => 'bob@example.com', 'role' => 'admin', ]); echo $newUser['id']; // 99 } catch (CommandException $e) { // Thrown on HTTP error or validation failure echo $e->getMessage(); } // --- Disable validation and raw-response processing --- $rawClient = new GuzzleClient($httpClient, $description, null, null, null, [ 'validate' => false, 'process' => false, // returns raw Psr7\Response ]); $response = $rawClient->GetUser(['id' => '1']); echo $response->getStatusCode(); // 200 echo $response->getBody(); // {"id":1,"name":"Alice",...} ``` -------------------------------- ### CreateUser Operation Source: https://context7.com/guzzle/guzzle-services/llms.txt Defines an operation to create a new user. Requires name and email, with an optional role. Data is sent in the JSON body. ```APIDOC ## POST /users ### Description Creates a new user with the provided name and email. An optional role can be specified. ### Method POST ### Endpoint /users ### Parameters #### Request Body - **name** (string) - Required - The name of the user. - **email** (string) - Required - The email address of the user. - **role** (string) - Optional - The role assigned to the user. Defaults to 'viewer'. ### Response #### Success Response (200) - **User** (object) - Contains the details of the newly created user. ``` -------------------------------- ### UploadFile Operation with Various Parameter Locations Source: https://context7.com/guzzle/guzzle-services/llms.txt Demonstrates the 'UploadFile' operation using different built-in request parameter locations: 'uri', 'query', 'header', 'json', and 'formParam'. It also shows how response data is extracted using 'location' in models. ```APIDOC ## POST /files/{folder_id} ### Description Uploads a file to a specified folder, supporting various parameter types for the request and response. ### Method POST ### Endpoint /files/{folder_id} ### Parameters #### Path Parameters - **folder_id** (string) - Required - The ID of the folder where the file will be uploaded. #### Query Parameters - **overwrite** (boolean) - Optional - Whether to overwrite the file if it already exists. #### Headers - **X-Upload-Token** (string) - Optional - An upload token for authentication. #### Request Body - **metadata** (object) - Optional - JSON object containing metadata for the file. - **filename** (string) - Optional - The name of the file to upload (sent as formParam). ### Request Example ```json { "folder_id": "folder-abc", "overwrite": true, "x_upload_token": "tok_xyz", "metadata": { "author": "alice", "tags": ["report", "q1"] }, "filename": "report-q1.pdf" } ``` ### Response #### Success Response (200) - **file_id** (string) - The ID of the uploaded file. - **url** (string) - The URL to access the uploaded file. - **status** (integer) - The HTTP status code of the response. - **reason** (string) - The HTTP reason phrase of the response. - **etag** (string) - The ETag header value from the response. ``` -------------------------------- ### Describe an API Action Source: https://context7.com/guzzle/guzzle-services/llms.txt Defines a single API action with its HTTP method, URI template, parameters, response model, and error responses. ```APIDOC ## `Operation` — Describe an API Action `Operation` represents a single API action. It is retrieved from a `Description` and exposes metadata about HTTP method, URI template, parameters, response model, and error responses. ```php use GuzzleHttp\Command\Guzzle\Description; $description = new Description([ 'baseUri' => 'https://api.example.com', 'operations' => [ 'DeleteItem' => [ 'httpMethod' => 'DELETE', 'uri' => '/items/{id}', 'summary' => 'Permanently delete an item', 'deprecated' => false, 'responseModel' => 'EmptyResponse', 'parameters' => [ 'id' => ['type' => 'string', 'location' => 'uri', 'required' => true], ], 'errorResponses' => [ ['code' => 404, 'phrase' => 'Not Found', 'class' => 'GuzzleHttp\Command\Exception\CommandException'], ['code' => 403, 'class' => 'GuzzleHttp\Command\Exception\CommandException'], ], ], ], 'models' => [ 'EmptyResponse' => ['type' => 'object'], ], ]); $op = $description->getOperation('DeleteItem'); echo $op->getName(); // DeleteItem echo $op->getHttpMethod(); // DELETE echo $op->getUri(); // /items/{id} echo $op->getSummary(); // Permanently delete an item var_dump($op->getDeprecated()); // bool(false) $idParam = $op->getParam('id'); var_dump($idParam->isRequired()); // bool(true) var_dump($idParam->getType()); // string(6) "string" var_dump($idParam->getLocation()); // string(3) "uri" $errors = $op->getErrorResponses(); echo $errors[0]['code']; // 404 echo $errors[0]['phrase']; // Not Found ``` ``` -------------------------------- ### Define Service API Description Source: https://context7.com/guzzle/guzzle-services/llms.txt Create a Description object to define a web service API, including its base URI, operations, and data models. Operations specify HTTP methods, URIs, parameters, and response models. Models define the structure of data. ```php use GuzzleHttp\Command\Guzzle\Description; $description = new Description([ 'name' => 'My API', 'apiVersion' => '1.0', 'baseUri' => 'https://api.example.com/v1', 'operations' => [ 'ListUsers' => [ 'httpMethod' => 'GET', 'uri' => '/users{?status,page,per_page}', 'summary' => 'List all users', 'responseModel' => 'UserCollection', 'parameters' => [ 'status' => ['type' => 'string', 'location' => 'uri', 'enum' => ['active', 'inactive']], 'page' => ['type' => 'integer', 'location' => 'uri', 'default' => 1], 'per_page' => ['type' => 'integer', 'location' => 'uri', 'maximum' => 100], ], ], 'GetUser' => [ 'httpMethod' => 'GET', 'uri' => '/users/{id}', 'responseModel' => 'User', 'parameters' => [ 'id' => ['type' => 'string', 'location' => 'uri', 'required' => true], ], ], 'CreateUser' => [ 'httpMethod' => 'POST', 'uri' => '/users', 'responseModel' => 'User', 'parameters' => [ 'name' => ['type' => 'string', 'location' => 'json', 'required' => true], 'email' => ['type' => 'string', 'location' => 'json', 'required' => true], 'role' => ['type' => 'string', 'location' => 'json', 'default' => 'viewer'], ], ], ], 'models' => [ 'User' => [ 'type' => 'object', 'properties' => [ 'id' => ['type' => 'integer', 'location' => 'json'], 'name' => ['type' => 'string', 'location' => 'json'], 'email' => ['type' => 'string', 'location' => 'json'], 'role' => ['type' => 'string', 'location' => 'json'], ], ], 'UserCollection' => [ 'type' => 'object', 'additionalProperties' => ['location' => 'json'], ], ], ]); // Introspection var_dump($description->hasOperation('GetUser')); // bool(true) var_dump($description->getApiVersion()); // string(3) "1.0" var_dump($description->getBaseUri()); // GuzzleHttp\Psr7\Uri object $op = $description->getOperation('CreateUser'); var_dump($op->getHttpMethod()); // string(4) "POST" var_dump($op->getParam('email')->isRequired()); // bool(true) ``` -------------------------------- ### PHP: Configure Custom Error Responses for Guzzle Operations Source: https://context7.com/guzzle/guzzle-services/llms.txt Define custom exception classes that extend `CommandException` and configure `errorResponses` in the service description to map HTTP status codes to these exceptions. This allows for granular error handling of API responses. ```php use GuzzleHttp\Client; use GuzzleHttp\Command\Guzzle\Description; use GuzzleHttp\Command\Guzzle\GuzzleClient; use GuzzleHttp\Command\Exception\CommandException; // Custom exception classes must extend CommandException class NotFoundException extends CommandException {} class RateLimitException extends CommandException {} $description = new Description([ 'baseUri' => 'https://api.example.com', 'operations' => [ 'GetResource' => [ 'httpMethod' => 'GET', 'uri' => '/resources/{id}', 'responseModel' => 'Resource', 'parameters' => [ 'id' => ['type' => 'string', 'location' => 'uri', 'required' => true], ], 'errorResponses' => [ // Matches status 404 regardless of reason phrase ['code' => 404, 'class' => NotFoundException::class], // Matches status 429 regardless of reason phrase ['code' => 429, 'class' => RateLimitException::class], // Exact match: code + phrase ['code' => 503, 'phrase' => 'Service Unavailable', 'class' => CommandException::class], ], ], ], 'models' => [ 'Resource' => ['type' => 'object', 'additionalProperties' => ['location' => 'json']], ], ]); $client = new GuzzleClient(new Client(), $description); try { $resource = $client->GetResource(['id' => 'missing-id']); } catch (NotFoundException $e) { echo 'Resource not found: ' . $e->getMessage(); } catch (RateLimitException $e) { echo 'Rate limit exceeded — retry after backoff'; } catch (CommandException $e) { echo 'Command error: ' . $e->getMessage(); } ``` -------------------------------- ### Operation Inheritance with `extends` Source: https://context7.com/guzzle/guzzle-services/llms.txt Allows an operation to inherit settings from another operation, overriding or adding specific fields to reduce duplication. ```APIDOC ## `Operation` Inheritance with `extends` An operation can inherit all parameters and settings from another operation using the `extends` key, then override or add specific fields. This eliminates duplication in service descriptions. ```php use GuzzleHttp\Command\Guzzle\Description; $description = new Description([ 'baseUri' => 'https://api.example.com', 'operations' => [ 'BaseListOp' => [ 'httpMethod' => 'GET', 'uri' => '/items{?page,per_page}', 'parameters' => [ 'page' => ['type' => 'integer', 'location' => 'query', 'default' => 1], 'per_page' => ['type' => 'integer', 'location' => 'query', 'default' => 20], ], 'responseModel' => 'ItemList', ], 'ListActiveItems' => [ 'extends' => 'BaseListOp', // inherits httpMethod, uri, per_page, page 'parameters' => [ 'status' => ['type' => 'string', 'location' => 'query', 'default' => 'active', 'static' => true], ], ], ], 'models' => [ 'ItemList' => ['type' => 'object', 'additionalProperties' => ['location' => 'json']], ], ]); $activeOp = $description->getOperation('ListActiveItems'); // Inherited parameter still accessible var_dump($activeOp->hasParam('page')); // bool(true) var_dump($activeOp->hasParam('status')); // bool(true) // Static value can't be overridden by callers var_dump($activeOp->getParam('status')->isStatic()); // bool(true) ``` ``` -------------------------------- ### FilterProducts Operation with Additional Parameters Source: https://context7.com/guzzle/guzzle-services/llms.txt Illustrates the 'FilterProducts' operation, which uses 'additionalParameters' to allow any extra query string parameters not explicitly defined in the operation schema. ```APIDOC ## GET /products ### Description Retrieves a list of products, allowing for flexible filtering via additional query parameters. ### Method GET ### Endpoint /products ### Parameters #### Query Parameters - **page** (integer) - Optional - The page number for the product list (defaults to 1). - **category** (string) - Optional - Filters products by category. - **brand** (string) - Optional - Filters products by brand. - **min_price** (string) - Optional - Filters products by minimum price. ### Request Example ```json { "page": 1, "category": "electronics", "brand": "acme", "min_price": "99.99" } ``` ### Response #### Success Response (200) - **products** (array) - A list of products matching the filter criteria. - **pagination** (object) - Pagination details for the product list. ``` -------------------------------- ### Reference Reusable Models with $ref Source: https://context7.com/guzzle/guzzle-services/llms.txt Define parameters that reuse shared schema definitions from the 'models' section using the '$ref' keyword. This promotes consistency and reduces redundancy for complex data structures like addresses or order items. ```php use GuzzleHttp\Command\Guzzle\Description; $description = new Description([ 'baseUri' => 'https://api.example.com', 'operations' => [ 'CreateOrder' => [ 'httpMethod' => 'POST', 'uri' => '/orders', 'responseModel' => 'Order', 'parameters' => [ 'shipping_address' => [ '$ref' => 'Address', // reuse shared Address model 'location' => 'json', ], 'items' => [ 'type' => 'array', 'location' => 'json', 'required' => true, 'items' => ['$ref' => 'OrderItem'], ], ], ], ], 'models' => [ 'Address' => [ 'type' => 'object', 'properties' => [ 'street' => ['type' => 'string', 'required' => true], 'city' => ['type' => 'string', 'required' => true], 'country' => ['type' => 'string', 'required' => true, 'minLength' => 2, 'maxLength' => 2], ], ], 'OrderItem' => [ 'type' => 'object', 'properties' => [ 'sku' => ['type' => 'string', 'required' => true], 'quantity' => ['type' => 'integer', 'required' => true, 'minimum' => 1], 'price' => ['type' => 'number', 'required' => true], ], ], 'Order' => [ 'type' => 'object', 'additionalProperties' => ['location' => 'json'], ], ], ]); ``` -------------------------------- ### CreateOrder Operation with Reusable Models Source: https://context7.com/guzzle/guzzle-services/llms.txt Defines the 'CreateOrder' operation that reuses 'Address' and 'OrderItem' models for its parameters, promoting schema reusability. ```APIDOC ## POST /orders ### Description Creates a new order with shipping address and a list of items. This operation utilizes reusable model definitions for complex parameter structures. ### Method POST ### Endpoint /orders ### Parameters #### Request Body - **shipping_address** (Address) - Required - The shipping address for the order. See the 'Address' model for details. - **items** (array) - Required - A list of items included in the order. Each item must conform to the 'OrderItem' model. ### Request Example ```json { "shipping_address": { "street": "123 Main St", "city": "Anytown", "country": "US" }, "items": [ { "sku": "ABC-123", "quantity": 2, "price": 19.99 }, { "sku": "XYZ-789", "quantity": 1, "price": 49.50 } ] } ``` ### Response #### Success Response (200) - **order_id** (string) - The unique identifier for the created order. ``` -------------------------------- ### Customize Query Parameter Serialization Source: https://github.com/guzzle/guzzle-services/blob/1.4/README.md Shows how to override the default query parameter serializer to handle array parameters differently, such as removing numeric indices for APIs that expect `foo[]=bar&foo[]=baz` instead of `foo[0]=bar&foo[1]=baz`. ```php $client->myMethod(['foo' => ['bar', 'baz']]); // Query params will be foo[0]=bar&foo[1]=baz ``` ```php use GuzzleHttp\Command\Guzzle\GuzzleClient; use GuzzleHttp\Command\Guzzle\RequestLocation\QueryLocation; use GuzzleHttp\Command\Guzzle\QuerySerializer\Rfc3986Serializer; use GuzzleHttp\Command\Guzzle\Serializer; $queryLocation = new QueryLocation('query', new Rfc3986Serializer(true)); $serializer = new Serializer($description, ['query' => $queryLocation]); $guzzleClient = new GuzzleClient($client, $description, $serializer); ```