Skip to content

Commit 6068fa6

Browse files
committed
feat: add decodeUsing method in Response of http client
1 parent 014f40d commit 6068fa6

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed

src/http-client/src/Response.php

Lines changed: 29 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,29 @@ 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+
public function decodeUsing(?Closure $callback): static
103+
{
104+
$this->decodeUsing = $callback;
105+
106+
return $this;
107+
}
108+
109+
/**
110+
* Decode the given response body.
111+
*/
112+
protected function decode(string $body, bool $asObject = false): array|object|null
113+
{
114+
if ($this->decodeUsing instanceof Closure) {
115+
return ($this->decodeUsing)($body, $asObject);
116+
}
117+
118+
return json_decode($body, ! $asObject);
92119
}
93120

94121
/**

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)