2626use ApiPlatform \State \Pagination \PaginatorInterface ;
2727use ApiPlatform \State \Pagination \PartialPaginatorInterface ;
2828use ApiPlatform \State \ProcessorInterface ;
29+ use ApiPlatform \State \Util \HttpResponseHeadersTrait ;
30+ use ApiPlatform \State \Util \HttpResponseStatusTrait ;
2931use Symfony \Component \HttpFoundation \Response ;
3032use Symfony \Component \HttpFoundation \StreamedResponse ;
3133use Symfony \Component \JsonStreamer \StreamWriterInterface ;
3234use Symfony \Component \TypeInfo \Type ;
3335
36+ /**
37+ * @implements ProcessorInterface<mixed,mixed>
38+ */
3439final class JsonStreamerProcessor implements ProcessorInterface
3540{
41+ use HttpResponseHeadersTrait;
42+ use HttpResponseStatusTrait;
43+
44+ /**
45+ * @param ProcessorInterface<mixed,mixed> $processor
46+ * @param StreamWriterInterface<array<string,mixed>> $jsonStreamer
47+ */
3648 public function __construct (
3749 private readonly ProcessorInterface $ processor ,
3850 private readonly StreamWriterInterface $ jsonStreamer ,
3951 private readonly string $ pageParameterName = 'page ' ,
4052 private readonly string $ enabledParameterName = 'pagination ' ,
41- private readonly int $ urlGenerationStrategy = UrlGeneratorInterface::ABS_PATH
53+ private readonly int $ urlGenerationStrategy = UrlGeneratorInterface::ABS_PATH ,
4254 ) {
4355 }
4456
@@ -67,6 +79,7 @@ private function getSearch(Operation $operation, string $requestUri): IriTemplat
6779 }
6880
6981 $ parts = parse_url ($ requestUri );
82+
7083 return new IriTemplate (
7184 variableRepresentation: 'BasicRepresentation ' ,
7285 mapping: $ mapping ,
@@ -120,7 +133,12 @@ private function getView(mixed $object, string $requestUri, Operation $operation
120133
121134 public function process (mixed $ data , Operation $ operation , array $ uriVariables = [], array $ context = [])
122135 {
123- if ($ context ['request ' ]->query ->has ('skip_json_stream ' )) {
136+ if (!$ operation ->getJsonStream () || !($ request = $ context ['request ' ] ?? null )) {
137+ return $ this ->processor ->process ($ data , $ operation , $ uriVariables , $ context );
138+ }
139+
140+ // TODO: remove this before merging
141+ if ($ request ->query ->has ('skip_json_stream ' )) {
124142 return $ this ->processor ->process ($ data , $ operation , $ uriVariables , $ context );
125143 }
126144
@@ -129,7 +147,7 @@ public function process(mixed $data, Operation $operation, array $uriVariables =
129147 }
130148
131149 if ($ operation instanceof CollectionOperationInterface) {
132- $ requestUri = $ context [ ' request ' ] ->getRequestUri () ?? '' ;
150+ $ requestUri = $ request ->getRequestUri () ?? '' ;
133151 $ collection = new Collection ();
134152 $ collection ->member = $ data ;
135153 $ collection ->view = $ this ->getView ($ data , $ requestUri , $ operation );
@@ -146,17 +164,25 @@ public function process(mixed $data, Operation $operation, array $uriVariables =
146164 $ collection ->totalItems = \count ($ data );
147165 }
148166
149- $ response = new StreamedResponse ($ this ->jsonStreamer ->write ($ collection , Type::generic (Type::object ($ collection ::class), Type::object ($ operation ->getClass ())), [
150- 'data ' => $ data ,
151- 'operation ' => $ operation ,
152- ]));
167+ $ data = $ this ->jsonStreamer ->write (
168+ $ collection ,
169+ Type::generic (Type::object ($ collection ::class), Type::object ($ operation ->getClass ())),
170+ ['data ' => $ data , 'operation ' => $ operation ],
171+ );
153172 } else {
154- $ response = new StreamedResponse ( $ this ->jsonStreamer ->write ($ data , Type::object ($ operation ->getClass ()), [
173+ $ data = $ this ->jsonStreamer ->write ($ data , Type::object ($ operation ->getClass ()), [
155174 'data ' => $ data ,
156175 'operation ' => $ operation ,
157- ])) ;
176+ ]);
158177 }
159178
179+ /** @var Iterable<string> $data */
180+ $ response = new StreamedResponse (
181+ $ data ,
182+ $ this ->getStatus ($ request , $ operation , $ context ),
183+ $ this ->getHeaders ($ request , $ operation , $ context )
184+ );
185+
160186 return $ this ->processor ->process ($ response , $ operation , $ uriVariables , $ context );
161187 }
162188}
0 commit comments