diff --git a/README.md b/README.md index 5d150e7..6f1ae11 100644 --- a/README.md +++ b/README.md @@ -535,6 +535,34 @@ echo $workflow->get("jobs.test.runs-on"); echo $workflow->get("on.0"); // push , the first event ``` +### Loading Data from JSON URL via Symfony HttpClient + +If you want more control over the HTTP request (headers, authentication, timeouts, retries, etc.) or your environment restricts PHP stream functions (for example `allow_url_fopen=0`), you can use `fromHttpJsonUrl()`. +This method relies on your Symfony HttpClient implementation and allows you to pass any request options supported by the client. + +```php +use HiFolks\DataType\Block; +use HiFolks\DataType\Enums\Operator; +use Symfony\Component\HttpClient\HttpClient; + +$url = "https://api.github.com/repos/hi-folks/data-block/commits"; +$client = HttpClient::create(); + +$commits = Block::fromHttpJsonUrl($url, $client, [ + 'headers' => [ + 'User-Agent' => 'my-app', + 'Accept' => 'application/json', + ], +]); + +$myCommits = $commits->where("commit.author.name", Operator::LIKE, "Roberto"); +foreach ($myCommits as $value) { + echo $value->get("commit.message") . PHP_EOL; +} +``` +Don't forget to install the client's implementation `composer require symfony/http-client` + + ## Adding and appending elements ### Appending the elements of a Block object to another Block object diff --git a/composer.json b/composer.json index 0047600..2d0545e 100644 --- a/composer.json +++ b/composer.json @@ -20,13 +20,18 @@ "require": { "php": "^8.2|^8.3|^8.4", "swaggest/json-schema": "^0.12.42", + "symfony/http-client-contracts": "^3.4.4", "symfony/yaml": "^6.4|^7.1" }, "require-dev": { "laravel/pint": "^1.2", "pestphp/pest": "^3.0", "phpstan/phpstan": "^2", - "rector/rector": "^2" + "rector/rector": "^2", + "symfony/http-client": "^7.4" + }, + "suggest": { + "symfony/http-client": "HTTP client implementation" }, "autoload": { "psr-4": { diff --git a/src/Traits/LoadableBlock.php b/src/Traits/LoadableBlock.php index f1f0c00..6b56c18 100644 --- a/src/Traits/LoadableBlock.php +++ b/src/Traits/LoadableBlock.php @@ -5,6 +5,7 @@ namespace HiFolks\DataType\Traits; use Symfony\Component\Yaml\Yaml; +use Symfony\Contracts\HttpClient\HttpClientInterface; trait LoadableBlock { @@ -56,6 +57,20 @@ public static function fromJsonUrl(string $jsonUrl, ?array $headers = null): sel } + /** + * @param array $options Symfony client's request options + */ + public static function fromHttpJsonUrl(string $jsonUrl, HttpClientInterface $client, array $options = []): self + { + $content = $client->request('GET', $jsonUrl, $options)->getContent(false); + + if ('' === $content) { + return self::make([]); + } + + return self::fromJsonString($content); + } + public static function fromYamlFile(string $yamlFile): self { if (file_exists($yamlFile)) { diff --git a/tests/Feature/UrlTest.php b/tests/Feature/UrlTest.php index 89b381b..d1d969c 100644 --- a/tests/Feature/UrlTest.php +++ b/tests/Feature/UrlTest.php @@ -1,6 +1,7 @@ group("url"); +it('remote json (Symfony\Contracts\HttpClient\HttpClientInterface)', function (): void { + $url = "https://api.github.com/repos/hi-folks/data-block/commits"; + + $commits = Block::fromHttpJsonUrl($url, HttpClient::create()); + expect($commits)->toBeInstanceOf(Block::class); + expect($commits)->toHaveCount(30); + + $myCommits = $commits->where("commit.author.name", "like", "Roberto"); + foreach ($myCommits as $value) { + expect($value->get("commit.message"))->toBeString(); + } + +})->group("url"); + it('remote dummyjson post', function (): void { $url = "https://dummyjson.com/posts";