{"id":18406313,"url":"https://github.com/programmatordev/php-api-sdk","last_synced_at":"2026-02-28T04:44:49.817Z","repository":{"id":227923012,"uuid":"753239939","full_name":"programmatordev/php-api-sdk","owner":"programmatordev","description":"A library for creating SDKs in PHP with PSR-18, PSR-17, PSR-6 and PSR-3 support","archived":false,"fork":false,"pushed_at":"2025-12-16T16:47:41.000Z","size":89,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-20T07:41:56.176Z","etag":null,"topics":["php-api","php-sdk","php8","psr-17","psr-18","psr-3","psr-6"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/programmatordev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-02-05T18:29:28.000Z","updated_at":"2025-12-16T16:47:13.000Z","dependencies_parsed_at":"2024-05-29T13:19:07.949Z","dependency_job_id":null,"html_url":"https://github.com/programmatordev/php-api-sdk","commit_stats":null,"previous_names":["programmatordev/php-api-sdk"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/programmatordev/php-api-sdk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/programmatordev%2Fphp-api-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/programmatordev%2Fphp-api-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/programmatordev%2Fphp-api-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/programmatordev%2Fphp-api-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/programmatordev","download_url":"https://codeload.github.com/programmatordev/php-api-sdk/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/programmatordev%2Fphp-api-sdk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29924827,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-27T19:37:42.220Z","status":"online","status_checked_at":"2026-02-28T02:00:07.010Z","response_time":90,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["php-api","php-sdk","php8","psr-17","psr-18","psr-3","psr-6"],"created_at":"2024-11-06T03:08:15.634Z","updated_at":"2026-02-28T04:44:49.810Z","avatar_url":"https://github.com/programmatordev.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PHP API SDK\n\n[![Latest Version](https://img.shields.io/github/release/programmatordev/php-api-sdk.svg?style=flat-square)](https://github.com/programmatordev/php-api-sdk/releases)\n[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)\n[![Tests](https://github.com/programmatordev/php-api-sdk/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/programmatordev/php-api-sdk/actions/workflows/ci.yml?query=branch%3Amain)\n\nA library for creating SDKs in PHP with support for:\n- [PSR-18 HTTP clients](https://www.php-fig.org/psr/psr-18);\n- [PSR-17 HTTP factories](https://www.php-fig.org/psr/psr-17);\n- [PSR-6 caches](https://www.php-fig.org/psr/psr-6);\n- [PSR-3 logs](https://www.php-fig.org/psr/psr-3);\n- Authentication;\n- Event listeners;\n- ...and more.\n\nAll methods are public for full hackability 🔥.\n\n## Requirements\n\n- PHP 8.1 or higher.\n\n## Installation\n\nInstall the library via [Composer](https://getcomposer.org/):\n\n```bash\ncomposer require programmatordev/php-api-sdk\n```\n\n## Basic Usage\n\nJust extend your API library with the `Api` class and have fun coding:\n\n```php\nuse ProgrammatorDev\\Api\\Api;\n\nclass YourApi extends Api\n{\n    public function __construct() \n    {\n        parent::__construct();\n        \n        // recommended config\n        $this-\u003esetBaseUrl('https://api.example.com/v1');\n    }\n    \n    public function getPosts(int $page = 1): string\n    {\n        // GET https://api.example.com/v1/posts?page=1\n        return $this-\u003erequest(\n            method: 'GET',\n            path: '/posts',\n            query: [\n               'page' =\u003e $page\n            ]\n        );\n    }\n}\n```\n\n## Documentation\n\n- [Base URL](#base-url)\n- [Requests](#requests)\n- [Query defaults](#query-defaults)\n- [Header defaults](#header-defaults)\n- [Authentication](#authentication)\n- [Event listeners](#event-listeners)\n- [HTTP client (PSR-18) and HTTP factories (PSR-17)](#http-client-psr-18-and-http-factories-psr-17)\n- [Cache (PSR-6)](#cache-psr-6)\n- [Logger (PSR-3)](#logger-psr-3)\n\n### Base URL\n\nGetter and setter for the base URL. \nBase URL is the common part of the API URL and will be used in all requests.\n\n```php\n$this-\u003esetBaseUrl(?string $baseUrl): self\n```\n\n```php\n$this-\u003egetBaseUrl(): ?string\n```\n\n### Requests\n\n- [`request`](#request)\n- [`buildPath`](#buildpath)\n\n#### `request`\n\nThis method is used to send a request to an API.\n\n```php\nuse Psr\\Http\\Message\\StreamInterface;\n\n$this-\u003erequest(\n    string $method, \n    string $path, \n    array $query = [], \n    array $headers = [], \n    StreamInterface|string $body = null\n): mixed\n```\n\n\u003e [!NOTE]\n\u003e A `ClientException` will be thrown if there is an error while processing the request.\n\nFor example, if you wanted to get a list of users with pagination:\n\n```php\nuse ProgrammatorDev\\Api\\Api;\n\nclass YourApi extends Api\n{\n    public function __construct() \n    {\n        parent::__construct();\n        \n        // recommended config\n        $this-\u003esetBaseUrl('https://api.example.com/v1');\n    }\n    \n    public function getUsers(int $page = 1, int $perPage = 20): string\n    {\n        // GET https://api.example.com/v1/users?page=1\u0026limit=20\n        return $this-\u003erequest(\n            method: 'GET',\n            path: '/users',\n            query: [\n                'page' =\u003e $page,\n                'limit' =\u003e $perPage\n            ]\n        );\n    }\n}\n```\n\nBy default, this method will return a `string` as it will be the response of the request as is.\nIf you want to change how the response is handled in all requests (for example, decode a JSON string into an array), \ncheck the [`addResponseContentsListener`](#addresponsecontentslistener) method in the [Event Listeners](#event-listeners) section.\n\n\u003e [!NOTE]\n\u003e If the `path` set is a full URL, it will be used as the request URL even if a `baseUrl` is set.\n\n#### `buildPath`\n\nThe purpose of this method is to have an easy way to build a properly formatted path depending on the inputs or parameters you might have.\n\n```php\n$this-\u003ebuildPath(string $path, array $parameters): string;\n```\n\nFor example, if you want to build a path that has a dynamic id:\n\n```php\nuse ProgrammatorDev\\Api\\Api;\n\nclass YourApi extends Api\n{\n    public function __construct() \n    {\n        parent::__construct();\n        \n        // recommended config\n        $this-\u003esetBaseUrl('https://api.example.com/v1');\n    }\n    \n    public function getPostComments(int $postId): string\n    {\n        // GET https://api.example.com/v1/posts/1/comments\n        return $this-\u003erequest(\n            method: 'GET',\n            path: $this-\u003ebuildPath('/posts/{postId}/comments', [\n                'postId' =\u003e $postId\n            ])\n        );\n    }\n}\n```\n\n### Query Defaults\n\nThese methods are used for handling default query parameters. \nDefault query parameters are applied to every API request.\n\n```php\n$this-\u003eaddQueryDefault(string $name, mixed $value): self\n```\n\n```php\n$this-\u003egetQueryDefault(string $name): mixed\n```\n\n```php\n$this-\u003eremoveQueryDefault(string $name): self\n```\n\nFor example, if you want to add a language query parameter in all requests:\n\n```php\nuse ProgrammatorDev\\Api\\Api;\n\nclass YourApi extends Api\n{\n    public function __construct(string $language = 'en') \n    {\n        // ...\n        \n        $this-\u003eaddQueryDefault('lang', $language);\n    }\n    \n    public function getPosts(): string\n    {\n        // GET https://api.example.com/v1/posts?lang=en\n        return $this-\u003erequest(\n            method: 'GET',\n            path: '/posts'\n        );\n    }\n    \n    public function getCategories(): string\n    {\n        // a query parameter with the same name, passed in the request method, will overwrite a query default\n        // GET https://api.example.com/v1/categories?lang=pt\n        return $this-\u003erequest(\n            method: 'GET',\n            path: '/categories',\n            query: [\n                'lang' =\u003e 'pt'\n            ]\n        );\n    }\n}\n```\n\n\u003e [!NOTE]\n\u003e A `query` parameter with the same name, passed in the `request` method, will overwrite a query default.\n\u003e Check the `getCategories` method in the example above.\n\n### Header Defaults\n\nThese methods are used for handling default headers.\nDefault headers are applied to every API request.\n\n```php\n$this-\u003eaddHeaderDefault(string $name, mixed $value): self\n```\n\n```php\n$this-\u003egetHeaderDefault(string $name): mixed\n```\n\n```php\n$this-\u003eremoveHeaderDefault(string $name): self\n```\n\nFor example, if you want to add a language header value in all requests:\n\n```php\nuse ProgrammatorDev\\Api\\Api;\n\nclass YourApi extends Api\n{\n    public function __construct(string $language = 'en') \n    {\n        // ...\n        \n        $this-\u003eaddHeaderDefault('X-LANGUAGE', $language);\n    }\n    \n    public function getPosts(): string\n    {\n        // GET https://api.example.com/v1/posts with an 'X-LANGUAGE' =\u003e 'en' header value\n        return $this-\u003erequest(\n            method: 'GET',\n            path: '/posts'\n        );\n    }\n    \n    public function getCategories(): string\n    {\n        // a header with the same name, passed in the request method, will overwrite a header default\n        // GET https://api.example.com/v1/categories with an 'X-LANGUAGE' =\u003e 'pt' header value\n        return $this-\u003erequest(\n            method: 'GET',\n            path: '/categories',\n            headers: [\n                'X-LANGUAGE' =\u003e 'pt'\n            ]\n        );\n    }\n}\n```\n\n\u003e [!NOTE]\n\u003e A header with the same name, passed in the `request` method, will overwrite a header default.\n\u003e Check the `getCategories` method in the example above.\n\n### Authentication\n\nGetter and setter for API authentication. \nUses the [authentication component](https://docs.php-http.org/en/latest/message/authentication.html) from [PHP HTTP](https://docs.php-http.org/en/latest/index.html).\n\n```php\nuse Http\\Message\\Authentication;\n\n$this-\u003esetAuthentication(?Authentication $authentication): self;\n```\n\n```php\nuse Http\\Message\\Authentication;\n\n$this-\u003egetAuthentication(): ?Authentication;\n```\n\nCheck all available authentication methods in the [PHP HTTP documentation](https://docs.php-http.org/en/latest/message/authentication.html#authentication-methods).\n\nYou can also [implement your own](https://docs.php-http.org/en/latest/message/authentication.html#implement-your-own) authentication method.\n\nFor example, if you have an API authenticated with a query parameter:\n\n```php\nuse ProgrammatorDev\\Api\\Api;\nuse Http\\Message\\Authentication\\QueryParam;\n\nclass YourApi extends Api\n{\n    public function __construct(string $applicationKey) \n    {\n        // ...\n        \n        $this-\u003esetAuthentication(\n            new QueryParam([\n                'api_token' =\u003e $applicationKey\n            ])\n        );\n    }\n    \n    public function getPosts(): string\n    {\n        // GET https://api.example.com/v1/posts?api_token=cd982h3diwh98dd23d32j\n        return $this-\u003erequest(\n            method: 'GET',\n            path: '/posts'\n        );\n    }\n}\n```\n\n### Event Listeners\n\n- [`addPreRequestListener`](#addprerequestlistener)\n- [`addPostRequestListener`](#addpostrequestlistener)\n- [`addResponseContentsListener`](#addresponsecontentslistener)\n- [Event Priority](#event-priority)\n- [Event Propagation](#event-propagation)\n\n#### `addPreRequestListener`\n\nThe `addPreRequestListener` method is used to add a function called before a request has been made.\nThis event listener will be applied to every API request.\n\n```php\n$this-\u003eaddPreRequestListener(callable $listener, int $priority = 0): self;\n```\n\nFor example:\n\n```php\nuse ProgrammatorDev\\Api\\Api;\nuse ProgrammatorDev\\Api\\Event\\PreRequestEvent;\n\nclass YourApi extends Api\n{\n    public function __construct() \n    {\n        // a PreRequestEvent is passed as an argument\n        $this-\u003eaddPreRequestListener(function(PreRequestEvent $event) {\n            $request = $event-\u003egetRequest();\n            \n            if ($request-\u003egetMethod() === 'POST') {\n                // do something for all POST requests\n                // ...\n            }\n        });\n    }\n    \n    // ...\n}\n```\n\nAvailable event methods:\n\n```php\n$this-\u003eaddPreRequestListener(function(PreRequestEvent $event) {\n    // get request data\n    $request = $event-\u003egetRequest();\n    // ...\n    // set request data\n    $event-\u003esetRequest($request);\n});\n```\n\n#### `addPostRequestListener`\n\nThe `addPostRequestListener` method is used to add a function called after a request has been made. \nThis function can be used to inspect the request and response data that was sent to, and received from, the API.\nThis event listener will be applied to every API request.\n\n```php\n$this-\u003eaddPostRequestListener(callable $listener, int $priority = 0): self;\n```\n\nFor example, you can use this event listener to handle API errors:\n\n```php\nuse ProgrammatorDev\\Api\\Api;\nuse ProgrammatorDev\\Api\\Event\\PostRequestEvent;\n\nclass YourApi extends Api\n{\n    public function __construct() \n    {\n        // a PostRequestEvent is passed as an argument\n        $this-\u003eaddPostRequestListener(function(PostRequestEvent $event) {\n            $response = $event-\u003egetResponse();\n            $statusCode = $response-\u003egetStatusCode();\n            \n            // if there was a response with an error status code\n            if ($statusCode \u003e= 400) {\n                // throw an exception\n                match ($statusCode) {\n                    400 =\u003e throw new BadRequestException(),\n                    404 =\u003e throw new NotFoundException(),\n                    default =\u003e throw new UnexpectedErrorException()\n                };\n            }\n        });\n    }\n    \n    // ...\n}\n```\n\nAvailable event methods:\n\n```php\n$this-\u003eaddPostRequestListener(function(PostRequestEvent $event) {\n    // get request data\n    $request = $event-\u003egetRequest();\n    // get response data\n    $response = $event-\u003egetResponse();\n    // ...\n    // set response data\n    $event-\u003esetResponse($response);\n});\n```\n\n#### `addResponseContentsListener`\n\nThe `addResponseContentsListener` method is used to manipulate the response received from the API.\nThis event listener will be applied to every API request.\n\n```php\n$this-\u003eaddResponseContentsListener(callable $listener, int $priority = 0): self;\n```\n\nFor example, if the API responses are JSON strings, you can use this event listener to decode them into arrays:\n\n```php\nuse ProgrammatorDev\\Api\\Api;\nuse ProgrammatorDev\\Api\\Event\\ResponseContentsEvent;\n\nclass YourApi extends Api\n{\n    public function __construct() \n    {\n        // a ResponseContentsEvent is passed as an argument\n        $this-\u003eaddResponseContentsListener(function(ResponseContentsEvent $event) {\n            // get response contents and decode json string into an array\n            $contents = $event-\u003egetContents();\n            $contents = json_decode($contents, true);\n            \n            // set handled contents\n            $event-\u003esetContents($contents);\n        });\n    }\n    \n    public function getPosts(): array\n    {\n        // will return an array\n        return $this-\u003erequest(\n            method: 'GET',\n            path: '/posts'\n        );\n    }\n}\n```\n\nAvailable event methods:\n\n```php\n$this-\u003eaddResponseContentsListener(function(ResponseContentsEvent $event) {\n    // get response body contents data\n    $contents = $event-\u003egetContents();\n    // ...\n    // set contents\n    $event-\u003esetContents($contents);\n});\n```\n\n#### Event Priority\n\nIt is possible to add multiple listeners for the same event and set the order in which they will be executed.\nBy default, they will be executed in the same order as they are added, but you can set a `priority` to control that order.\nEvent listeners are then executed from the highest priority to the lowest:\n\n```php\nuse ProgrammatorDev\\Api\\Api;\nuse ProgrammatorDev\\Api\\Event\\ResponseContentsEvent;\n\nclass YourApi extends Api\n{\n    public function __construct() \n    {\n        // two event listeners are added,\n        // but the second is executed first (higher priority) even though it was added after\n        \n        // executed last (lower priority)\n        $this-\u003eaddResponseContentsListener(\n            listener: function(ResponseContentsEvent $event) { ... }, \n            priority: 0\n        );\n        \n        // executed first (higher priority)\n        $this-\u003eaddResponseContentsListener(\n            listener: function(ResponseContentsEvent $event) { ... }, \n            priority: 10\n        ); \n    }\n}\n```\n\n#### Event Propagation\n\nIn some cases, you may want to stop the event flow and prevent listeners from being called.\nFor that, you can use the `stopPropagation()` method:\n\n```php\nuse ProgrammatorDev\\Api\\Api;\nuse ProgrammatorDev\\Api\\Event\\ResponseContentsEvent;\n\nclass YourApi extends Api\n{\n    public function __construct() \n    {\n        $this-\u003eaddResponseContentsListener(function(ResponseContentsEvent $event) {\n            // stop propagation so future listeners of this event will not be called\n            $event-\u003estopPropagation();\n        });\n        \n        // this listener will not be called\n        $this-\u003eaddResponseContentsListener(function(ResponseContentsEvent $event) { \n            // ...\n        }); \n    }\n}\n```\n\n### HTTP Client (PSR-18) and HTTP Factories (PSR-17)\n\n- [HTTP client and HTTP factory adapters](#http-client-and-http-factory-adapters)\n- [Plugin system](#plugin-system)\n\n#### HTTP Client and HTTP Factory Adapters\n\nBy default, this library makes use of the [HTTPlug's Discovery](https://github.com/php-http/discovery) library.\nThis means that it will automatically find and install a well-known PSR-18 client and PSR-17 factory implementation for you \n(if they were not found on your project):\n- [PSR-18 compatible implementations](https://packagist.org/providers/psr/http-client-implementation)\n- [PSR-17 compatible implementations](https://packagist.org/providers/psr/http-factory-implementation)\n\n```php\nuse ProgrammatorDev\\Api\\Builder\\ClientBuilder;\n\nnew ClientBuilder(\n    // a PSR-18 client\n    ?ClientInterface $client = null,\n    // a PSR-17 request factory\n    ?RequestFactoryInterface $requestFactory = null,\n    // a PSR-17 stream factory\n    ?StreamFactoryInterface $streamFactory = null\n);\n```\n\n```php\nuse ProgrammatorDev\\Api\\Builder\\ClientBuilder;\n\n$this-\u003esetClientBuilder(ClientBuilder $clientBuilder): self;\n```\n\n```php\nuse ProgrammatorDev\\Api\\Builder\\ClientBuilder;\n\n$this-\u003egetClientBuilder(): ClientBuilder;\n```\n\nIf you don't want to rely on the discovery of implementations, you can set the ones you want:\n\n```php\nuse ProgrammatorDev\\Api\\Api;\nuse ProgrammatorDev\\Api\\Builder\\ClientBuilder;\nuse Symfony\\Component\\HttpClient\\Psr18Client;\nuse Nyholm\\Psr7\\Factory\\Psr17Factory;\n\nclass YourApi extends Api\n{\n    public function __construct() \n    {\n        // ...\n        \n        $client = new Psr18Client();\n        $requestFactory = $streamFactory = new Psr17Factory();\n        \n        $this-\u003esetClientBuilder(\n            new ClientBuilder(\n                client: $client, \n                requestFactory: $requestFactory, \n                streamFactory: $streamFactory\n            )\n        );\n    }\n}\n```\n\n#### Plugin System\n\nThis library enables attaching plugins to the HTTP client. \nA plugin modifies the behavior of the client by intercepting the request and response flow. \n\nSince plugin order matters, a plugin is added with a priority level and is executed in descending order from highest to lowest.\n\nCheck all the [available plugins](https://docs.php-http.org/en/latest/plugins/index.html) or [create your own](https://docs.php-http.org/en/latest/plugins/build-your-own.html).\n\n```php\nuse Http\\Client\\Common\\Plugin;\n\n$this-\u003egetClientBuilder()-\u003eaddPlugin(Plugin $plugin, int $priority): self;\n```\n\nIt is important to know that this library already uses various plugins with different priorities.\nThe following list has all the implemented plugins with the respective priority in descending order (remember that order matters):\n\n| Plugin                                                                                     | Priority | Note                              |\n|--------------------------------------------------------------------------------------------|----------|-----------------------------------|\n| [`ContentTypePlugin`](https://docs.php-http.org/en/latest/plugins/content-type.html)       | 40       |                                   |\n| [`ContentLengthPlugin`](https://docs.php-http.org/en/latest/plugins/content-length.html)   | 32       |                                   |\n| [`AuthenticationPlugin`](https://docs.php-http.org/en/latest/plugins/authentication.html)  | 24       | only if authentication is enabled | \n| [`CachePlugin`](https://docs.php-http.org/en/latest/plugins/cache.html)                    | 16       | only if cache is enabled          |\n| [`LoggerPlugin`](https://docs.php-http.org/en/latest/plugins/logger.html)                  | 8        | only if logger is enabled         |\n\n\u003e [!IMPORTANT]\n\u003e The plugin priority in the list above is reserved.\n\u003e This means that if you try to add any plugin with the same priority, it will be overwritten.\n\nFor example, if you wanted the client to automatically attempt to re-send a request that failed\n(due to unreliable connections and servers, for example), you can add the [RetryPlugin](https://docs.php-http.org/en/latest/plugins/retry.html):\n\n```php\nuse ProgrammatorDev\\Api\\Api;\nuse Http\\Client\\Common\\Plugin\\RetryPlugin;\n\nclass YourApi extends Api\n{\n    public function __construct() \n    {\n        // ...\n        \n        // if a request fails, it will retry at least 3 times\n        // the priority is 20 to execute before the cache plugin\n        // (check the above plugin order list for more information)\n        $this-\u003egetClientBuilder()-\u003eaddPlugin(\n            plugin: new RetryPlugin(['retries' =\u003e 3]),\n            priority: 20\n        );\n    }\n}\n```\n\n### Cache (PSR-6)\n\nThis library allows configuring the cache layer of the client for making API requests. \nIt uses a standard PSR-6 implementation and provides methods to fine-tune how HTTP caching behaves:\n- [PSR-6 compatible implementations](https://packagist.org/providers/psr/cache-implementation)\n\n```php\nuse ProgrammatorDev\\Api\\Builder\\CacheBuilder;\nuse Psr\\Cache\\CacheItemPoolInterface;\n\nnew CacheBuilder(\n    // a PSR-6 cache adapter\n    CacheItemPoolInterface $pool,\n    // default lifetime (in seconds) of cached items\n    ?int $ttl = 60,\n    // An array of HTTP methods for which caching should be applied\n    $methods = ['GET', 'HEAD'],\n    // An array of cache directives to be compared with the headers of the HTTP response to determine cacheability\n    $responseCacheDirectives = ['max-age'] \n);\n```\n\n```php\nuse ProgrammatorDev\\Api\\Builder\\CacheBuilder;\n\n$this-\u003esetCacheBuilder(CacheBuilder $cacheBuilder): self;\n```\n\n```php\nuse ProgrammatorDev\\Api\\Builder\\CacheBuilder;\n\n$this-\u003egetCacheBuilder(): CacheBuilder;\n```\n\nFor example, if you wanted to set a file-based cache adapter:\n\n```php\nuse ProgrammatorDev\\Api\\Api;\nuse ProgrammatorDev\\Api\\Builder\\CacheBuilder;\nuse Symfony\\Component\\Cache\\Adapter\\FilesystemAdapter;\n\nclass YourApi extends Api\n{\n    public function __construct() \n    {\n        // ...\n        \n        $pool = new FilesystemAdapter();\n        \n        // file-based cache adapter with a 1-hour default cache lifetime\n        $this-\u003esetCacheBuilder(\n            new CacheBuilder(\n                pool: $pool, \n                ttl: 3600\n            )\n        );\n    }\n    \n    public function getPosts(): string\n    {\n        // you can change the lifetime (and all other parameters)\n        // for this specific endpoint\n        $this-\u003egetCacheBuilder()-\u003esetTtl(600);\n       \n        return $this-\u003erequest(\n            method: 'GET',\n            path: '/posts'\n        );\n    }\n}\n```\n\n### Logger (PSR-3)\n\nThis library allows configuring a logger to save data for making API requests.\nIt uses a standard PSR-3 implementation and provides methods to fine-tune how logging behaves:\n- [PSR-3 compatible implementations](https://packagist.org/providers/psr/log-implementation)\n\n```php\nuse ProgrammatorDev\\Api\\Builder\\LoggerBuilder;\nuse Psr\\Log\\LoggerInterface;\nuse Http\\Message\\Formatter;\nuse Http\\Message\\Formatter\\SimpleFormatter;\n\nnew LoggerBuilder(\n    // a PSR-3 logger adapter\n    LoggerInterface $logger,\n     // determines how the log entries will be formatted when they are written by the logger\n     // if no formatter is provided, it will default to a SimpleFormatter instance\n    ?Formatter $formatter = null\n);\n```\n\n```php\nuse ProgrammatorDev\\Api\\Builder\\LoggerBuilder;\n\n$this-\u003esetLoggerBuilder(LoggerBuilder $loggerBuilder): self;\n```\n\n```php\nuse ProgrammatorDev\\Api\\Builder\\LoggerBuilder;\n\n$this-\u003egetLoggerBuilder(): LoggerBuilder;\n```\n\nAs an example, if you wanted to save logs into a file:\n\n```php\nuse ProgrammatorDev\\Api\\Api;\nuse ProgrammatorDev\\Api\\Builder\\LoggerBuilder;\nuse Monolog\\Logger;\nuse Monolog\\Handler\\StreamHandler;\n\nclass YourApi extends Api\n{\n    public function __construct() \n    {\n        // ...\n        \n        $logger = new Logger('api');\n        $logger-\u003epushHandler(new StreamHandler('/logs/api.log'));\n        \n        $this-\u003esetLoggerBuilder(\n            new LoggerBuilder(\n                logger: $logger\n            )\n        );\n    }\n}\n```\n\n## Libraries using PHP API SDK\n\n- [programmatordev/openweathermap-php-api](https://github.com/programmatordev/openweathermap-php-api)\n- [programmatordev/sportmonksfootball-php-api](https://github.com/programmatordev/sportmonksfootball-php-api)\n\n## Contributing\n\nAny form of contribution to improve this library (including requests) will be welcome and appreciated.\nMake sure to open a pull request or issue.\n\n## License\n\nThis project is licensed under the MIT license.\nPlease see the [LICENSE](LICENSE) file distributed with this source code for further information regarding copyright and licensing.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprogrammatordev%2Fphp-api-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprogrammatordev%2Fphp-api-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprogrammatordev%2Fphp-api-sdk/lists"}