Skip to content

Commit f39d683

Browse files
author
Admin
committed
New streamed json response
1 parent 0218885 commit f39d683

File tree

1 file changed

+124
-0
lines changed

1 file changed

+124
-0
lines changed
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
<?php
2+
3+
namespace MacropaySolutions\LaravelCrudWizard\Responses;
4+
5+
use Illuminate\Contracts\Support\Arrayable;
6+
use Illuminate\Contracts\Support\Jsonable;
7+
use Symfony\Component\HttpFoundation\JsonResponse;
8+
use Symfony\Component\HttpFoundation\StreamedResponse;
9+
10+
/**
11+
* StreamedJsonResponse represents a streamed HTTP response for JSONs
12+
*
13+
* Example usage:
14+
*
15+
* $response = new StreamedJsonResponse(Operation::query()->with('client')->lazyByIdDesc(1000, 'id'), 200, [
16+
* StreamedJsonResponse::META_DATA => \json_encode(\array_merge([ // use this only if you want metaData info
17+
* 'has_more_pages' => false,
18+
* ], $appends, $paginator instanceof Paginator ? [
19+
* 'current_page' => 1,
20+
* 'from' => 1,
21+
* 'per_page' => $paginator->perPage(),
22+
* 'to' => $paginator->perPage(),
23+
* 'data' => [],
24+
* ] : [
25+
* 'current_page' => 1,
26+
* 'from' => 1,
27+
* 'last_page' => 1,
28+
* 'per_page' => $paginator->total(),
29+
* 'to' => $paginator->total(),
30+
* 'total' => $paginator->total(),
31+
* 'data' => [],
32+
* ]))
33+
* ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); // DO NOT use JSON_PRETTY_PRINT to avoid issues with \n
34+
*
35+
* Example streamed response:
36+
* Header:
37+
*
38+
* metaData: {
39+
* "has_more_pages": false,
40+
* "sums": {
41+
* "value": null
42+
* },
43+
* "avgs": {
44+
* "value_avg": null
45+
* },
46+
* "mins": {
47+
* "value_min": null,
48+
* "created_at_min": null
49+
* },
50+
* "maxs": {
51+
* "value_max": null,
52+
* "created_at_max": null
53+
* },
54+
* "index_required_on_filtering": [
55+
* "id",
56+
* "created_at"
57+
* ],
58+
* "current_page": 1,
59+
* "from": 1,
60+
* "last_page": 1,
61+
* "per_page": 17009,
62+
* "to": 17009,
63+
* "total": 17009,
64+
* "data": []
65+
* }
66+
*
67+
* Body:
68+
*
69+
* {'id':17009,'value':'92.00','created_at':'2024-01-17 09:17:11','updated_at':null,'primary_key_identifier':'17009'}
70+
* {'id':17008,'value':'87.00','created_at':'2024-01-17 09:17:11','updated_at':null,'primary_key_identifier':'17008'}
71+
* ...
72+
*/
73+
class StreamedJsonResponse extends StreamedResponse
74+
{
75+
public const META_DATA= 'metaData';
76+
public function __construct(
77+
private iterable $data,
78+
int $status = 200,
79+
array $headers = [],
80+
private int $encodingOptions = JsonResponse::DEFAULT_ENCODING_OPTIONS,
81+
) {
82+
parent::__construct(function (): void {
83+
$prefix = null;
84+
85+
foreach ($this->data as $item) {
86+
if ($item instanceof Jsonable) {
87+
echo $prefix . $item->toJson(\JSON_THROW_ON_ERROR | $this->encodingOptions);
88+
\ob_flush();
89+
\flush();
90+
$prefix ??= "\n";
91+
92+
continue;
93+
}
94+
95+
if ($item instanceof \JsonSerializable) {
96+
echo $prefix . \json_encode($item->jsonSerialize(), \JSON_THROW_ON_ERROR | $this->encodingOptions);
97+
\ob_flush();
98+
\flush();
99+
$prefix ??= "\n";
100+
101+
continue;
102+
}
103+
104+
if ($item instanceof Arrayable) {
105+
echo $prefix . \json_encode($item->toArray(), \JSON_THROW_ON_ERROR | $this->encodingOptions);
106+
\ob_flush();
107+
\flush();
108+
$prefix ??= "\n";
109+
110+
continue;
111+
}
112+
113+
echo $prefix . \json_encode((array)$item, \JSON_THROW_ON_ERROR | $this->encodingOptions);
114+
\ob_flush();
115+
\flush();
116+
$prefix ??= "\n";
117+
}
118+
}, $status, $headers);
119+
120+
if (!$this->headers->get('Content-Type')) {
121+
$this->headers->set('Content-Type', 'application/json');
122+
}
123+
}
124+
}

0 commit comments

Comments
 (0)