{"id":23113763,"url":"https://github.com/waffler-io/waffler","last_synced_at":"2025-10-05T02:10:30.108Z","repository":{"id":62545999,"uuid":"430507237","full_name":"waffler-io/waffler","owner":"waffler-io","description":"Declarative HTTP Clients using Guzzle HTTP Library and PHP 8 Attributes","archived":false,"fork":false,"pushed_at":"2025-08-30T04:08:13.000Z","size":698,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-30T06:08:13.742Z","etag":null,"topics":["api","api-client","api-rest","declarative-programming","guzzle-php-library","guzzlehttp","http-client","library","php","php-attibutes","php8"],"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/waffler-io.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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":"2021-11-21T23:40:53.000Z","updated_at":"2025-08-30T04:07:06.000Z","dependencies_parsed_at":"2023-11-29T00:41:47.297Z","dependency_job_id":"dbea59a2-4b76-401a-9a33-a6d620a7221f","html_url":"https://github.com/waffler-io/waffler","commit_stats":{"total_commits":94,"total_committers":2,"mean_commits":47.0,"dds":0.0957446808510638,"last_synced_commit":"cef4d1f3a1257ea8758faeeb3bb6627ec730c614"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"purl":"pkg:github/waffler-io/waffler","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/waffler-io%2Fwaffler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/waffler-io%2Fwaffler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/waffler-io%2Fwaffler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/waffler-io%2Fwaffler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/waffler-io","download_url":"https://codeload.github.com/waffler-io/waffler/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/waffler-io%2Fwaffler/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278399690,"owners_count":25980332,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-05T02:00:06.059Z","response_time":54,"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":["api","api-client","api-rest","declarative-programming","guzzle-php-library","guzzlehttp","http-client","library","php","php-attibutes","php8"],"created_at":"2024-12-17T03:13:36.799Z","updated_at":"2025-10-05T02:10:30.082Z","avatar_url":"https://github.com/waffler-io.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Build](https://github.com/waffler-io/waffler/actions/workflows/php-ci.yml/badge.svg)\n[![License](https://img.shields.io/github/license/waffler-io/waffler)](LICENSE)\n[![Total Downloads](https://img.shields.io/packagist/dt/waffler/waffler.svg)](https://packagist.org/packages/waffler/waffler)\n\n# Waffler\n\n\u003chr\u003e\n\n### How to install?\n\n```shell\n$ composer require waffler/waffler\n```\n\n- This package requires PHP 8 or above.\n\n### How to test?\n\n```shell\n$ composer phpunit\n```\n\n## Quick start\n\nFor our example, lets imagine that we want to consume an ordinary API: `https://foo-bar.baz/api`\n\nOur objectives are:\n\n- Perform the login to retrieve the authorization token.\n- Retrieve all posts from the database.\n\n#### Step 1: Create the basic interface for your client.\n\n```php\n\u003c?php // FooClient.php\n\nnamespace App\\Clients;\n\ninterface FooClient\n{\n    /**\n     * Retrieve authorization token.\n     *\n     * @param array $credentials Just pass the login and password.\n     * @return array             The json response.\n     */\n    public function login(array $credentials): array;\n\n    /**\n     * Retrieve all posts.\n     *\n     * @param string $authToken The authorization token.\n     * @param array $query      Some optional query string Filters.\n     * @return array            The list of posts.\n     */\n    public function getPosts(string $authToken, array $query = []): array;\n}\n```\n\n#### Step 2: Annotate the methods with Waffler Attributes.\n\nThe magic is almost done. Now we need to annotate the methods and parameters to \"teach\" Waffler how to make the\nrequests. There are dozens of Attributes, but for this example we just need 5 of them.\n\nImport the Attributes from the `Waffler\\Waffler\\Attributes` namespace.\n\n```php\n\u003c?php // FooClient.php\n\nnamespace App\\Clients;\n\nuse Waffler\\Waffler\\Attributes\\Auth\\Bearer;\nuse Waffler\\Waffler\\Attributes\\Request\\Json;\nuse Waffler\\Waffler\\Attributes\\Request\\Query;\nuse Waffler\\Waffler\\Attributes\\Verbs\\Get;\nuse Waffler\\Waffler\\Attributes\\Verbs\\Post;\n\ninterface FooClient\n{\n    /**\n     * Retrieve authorization token.\n     *\n     * @param array $credentials Pass the login and password.\n     * @return array             The json response.\n     */\n    #[Post('/auth/login')]\n    public function login(#[Json] array $credentials): array;\n\n    /**\n     * Retrieve all posts.\n     *\n     * @param string $authToken The authorization token.\n     * @param array $query      Some optional query string Filters.\n     * @return array            The list of posts.\n     */\n    #[Get('/posts')]\n    public function getPosts(#[Bearer] string $authToken, #[Query] array $query = []): array;\n}\n```\n\n#### Step 3: Generate the implementation for your interface and use it.\n\nImport the class `Waffler\\Waffler\\Client\\Factory` and call the static method `make` passing the\n_fully qualified name_ of the interface we just created as first argument and an associative array of GuzzleHttp client\noptions as second argument.\n\n```php\n\u003c?php\n\nnamespace App;\n\nuse App\\Clients\\FooClient;\nuse Waffler\\Waffler\\Client\\Factory;\n\n// Instantiate the client passing the interface as first argument.\n$fooClient = Factory::make(FooClient::class, ['base_uri' =\u003e '\u003capi-base-uri\u003e']);\n\n// Retrieve the credentials\n$credentials = $this-\u003efooClient-\u003elogin([\n    'email' =\u003e 'email@test.com',\n    'password' =\u003e '\u003csecret\u003e'\n]);\n\n// Retrieve the posts.\n$posts = $this-\u003efooClient-\u003egetPosts($credentials['token'], ['created_at' =\u003e '2020-01-01'])\n```\n\n## Usage examples\n\nSee the [Examples folder](./examples).\n\n## Attributes docs\n\nSee the [wiki](https://github.com/waffler-io/waffler/wiki/The-Waffler-Attributes) for more information about the Attributes.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwaffler-io%2Fwaffler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwaffler-io%2Fwaffler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwaffler-io%2Fwaffler/lists"}