Hola Habr!
Me senté una vez e intenté darle al JSON frontal con bienes raíces, que tenían muchas dependencias. Symfony 4, la paginación knp y JMSSerializer estaban en la parte posterior, bueno, en principio, cosas estándar, pero el problema es que cuando intentas dar un objeto con todas las entidades y colecciones anidadas, todo comienza a disminuir en el nivel de serialización de estos datos.
Primero debe hacer una solicitud a la base de datos, luego el serializador extraerá gradualmente todo lo demás, luego todo estará envuelto en JSON y solo entonces todo volverá al frente.
Idea
Tuve una idea, por qué no devolver JSON directamente desde la base de datos directamente al frente desde atrás, sí, necesitas escribir un SQL increíble, pero puedes hacer una herramienta que lo haga por ti. Me puse a escribir una idea, un repositorio en un github , basado en el modelo de datos de la doctrina, comunicaciones OneToOne, ManyToOne, OneToMany y ManyToMany. Además, esta herramienta se puede atornillar fácilmente a Symfony 4 y se configurará a sí misma, como resultado, solo necesita inyectar la fábrica QueryBuilderFactory y obtener el QueryBuilder desde allí para la tabla deseada por clase de entidad.
Mi serializador también usa grupos de serialización que puede establecer usando la anotación Exponer en el campo de entidad, no olvide adjuntar la anotación de Tabla a la entidad y especificar el alias de la tabla, es mejor usar los que normalmente especifica.
Ejemplo de generación de SQL
<?php use \Mash\MysqlJsonSerializer\QueryBuilder\Table\JoinStrategy\FieldStrategy; use \Mash\MysqlJsonSerializer\Wrapper\FieldWrapper; use \Mash\MysqlJsonSerializer\QueryBuilder\Table\Table; use \Mash\MysqlJsonSerializer\Wrapper\Mapping; use \Mash\MysqlJsonSerializer\QueryBuilder\QueryBuilder; $oneToManyTable = (new Table('advert_group', 'adg', 'adg_id')) ->addSimpleField('adg_id') ->addSimpleField('adg_name') ; $table = (new Table('estate', 'est', 'est_id')) ->addSimpleField('est_id') ->addSimpleField('est_name') ->addOneToManyField($oneToManyTable, 'advert_groups', new FieldStrategy('adg_estate')); $mapping = new Mapping(); $mapping ->addMap($table, 'est_id', 'id') ->addMap($table, 'est_name', 'name') ->addMap($oneToManyTable, 'adg_id', 'id') ->addMap($oneToManyTable, 'adg_name', 'name'); $builder = new QueryBuilder($table, new FieldWrapper($mapping)); $builder ->setOffset(2) ->setLimit(1); $sql = $builder->jsonArray();
Como resultado, se generará el siguiente SQL:
SELECT JSON_ARRAYAGG(JSON_OBJECT('id',est_res.est_id,'name',est_res.est_name,'advert_groups',(SELECT JSON_ARRAYAGG(JSON_OBJECT('id',adg.adg_id,'name',adg.adg_name)) FROM advert_group adg INNER JOIN estate est_2 ON est_2.est_id = adg.adg_estate WHERE est_2.est_id = est_res.est_id))) FROM (SELECT * FROM estate est LIMIT 1 OFFSET 2) est_res
Resultado:
[{"id": 3, "name": ", , 31", "advert_groups": [{"id": 10, "name": "avito-1115362430"}]}]
Resumen
Las instrucciones completas de uso pronto se agregarán al repositorio de github. Como resultado, cuando atornillé esto en mi proyecto, recibí respuestas muy rápidas de la API REST y al mismo tiempo pude devolver muchos objetos con muchas dependencias anidadas, por ejemplo, lo que quería obtener a través de JMSSerializer que obtuve durante 40 segundos, ahora por 230 milisegundos, y esto siempre que Kernel Subscriber lea las anotaciones en los campos de la entidad a través de la reflexión, quiero implementar esto pronto a través de la caché Symfony.
El artículo se complementará ...
Segunda parte