Skip to content

Commit add82b0

Browse files
authored
Merge pull request #302 from hypervel/albert/feature/http-client-decode-using
feat: add decodeUsing method in Response of http client
2 parents 2dabd18 + 5c267f0 commit add82b0

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

src/http-client/src/Response.php

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ class Response implements ArrayAccess, Stringable
3333
*/
3434
protected array $decoded = [];
3535

36+
/**
37+
* The custom decode callback.
38+
*/
39+
protected ?Closure $decodeUsing = null;
40+
3641
/**
3742
* The request cookies.
3843
*/
@@ -64,7 +69,7 @@ public function body(): string
6469
public function json(?string $key = null, mixed $default = null): mixed
6570
{
6671
if (! $this->decoded) {
67-
$this->decoded = json_decode($this->body(), true) ?? [];
72+
$this->decoded = $this->decode($this->body());
6873
}
6974

7075
if (is_null($key)) {
@@ -88,7 +93,34 @@ public function json(?string $key = null, mixed $default = null): mixed
8893
*/
8994
public function object(): array|object|null
9095
{
91-
return json_decode($this->body(), false);
96+
return $this->decode($this->body(), true);
97+
}
98+
99+
/**
100+
* Set a custom decode callback.
101+
*
102+
* The callback will be invoked with the following parameters:
103+
* - string $body: The raw response body.
104+
* - bool $asObject: When true, the decoder should return an array of objects.
105+
*/
106+
public function decodeUsing(?Closure $callback): static
107+
{
108+
$this->decodeUsing = $callback;
109+
$this->decoded = [];
110+
111+
return $this;
112+
}
113+
114+
/**
115+
* Decode the given response body.
116+
*/
117+
protected function decode(string $body, bool $asObject = false): array|object|null
118+
{
119+
if ($this->decodeUsing instanceof Closure) {
120+
return ($this->decodeUsing)($body, $asObject);
121+
}
122+
123+
return json_decode($body, ! $asObject);
92124
}
93125

94126
/**

tests/HttpClient/HttpClientTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,29 @@ public function testResponseCanBeReturnedAsFluent()
430430
$this->assertEquals(new Fluent([]), $response->fluent('missing_key'));
431431
}
432432

433+
public function testResponseDecodeUsingWithDifferentFormats()
434+
{
435+
$this->factory->fake([
436+
'*' => 'name:Taylor|framework:Laravel',
437+
]);
438+
439+
$response = $this->factory->get('http://foo.com/api')->decodeUsing(function ($body) {
440+
$parts = explode('|', $body);
441+
$result = [];
442+
443+
foreach ($parts as $part) {
444+
[$key, $value] = explode(':', $part);
445+
$result[$key] = $value;
446+
}
447+
448+
return $result;
449+
});
450+
451+
$this->assertSame('Taylor', $response->json('name'));
452+
$this->assertSame('Laravel', $response->json('framework'));
453+
$this->assertIsArray($response->json());
454+
}
455+
433456
public function testSendRequestBodyAsJsonByDefault()
434457
{
435458
$body = '{"test":"phpunit"}';

0 commit comments

Comments
 (0)