Halo, Habr!
Saya duduk sekali dan mencoba memberi JSON depan dengan real estat, yang memiliki banyak ketergantungan. Symfony 4, knp pagination dan JMSSerializer ada di belakang, well, pada prinsipnya, hal-hal standar, tetapi masalahnya adalah ketika Anda mencoba untuk memberikan objek dengan semua entitas bersarang dan koleksi, semuanya mulai melambat pada tingkat serialisasi data ini.
Pertama Anda perlu membuat permintaan ke database, maka serializer akan secara bertahap menarik segala sesuatu yang lain, maka semuanya akan dibungkus dalam JSON dan hanya kemudian semuanya akan kembali ke depan.
Ide
Saya punya ide, dan mengapa tidak mengembalikan JSON langsung dari database langsung ke depan dari belakang, ya, Anda perlu menulis SQL yang mengagumkan, tetapi Anda dapat membuat alat yang melakukan ini untuk Anda. Saya mulai menulis ide, repositori pada github , berdasarkan pada model data dari doktrin, OneToOne, ManyToOne, OneToMany, dan ManyToMany komunikasi. Selain itu, alat ini dapat dengan mudah dipasangkan ke Symfony 4 dan itu akan mengkonfigurasi sendiri, sebagai hasilnya, Anda hanya perlu menyuntikkan pabrik QueryBuilderFactory dan dapatkan dari sana QueryBuilder untuk tabel yang diinginkan berdasarkan kelas entitas.
Serializer saya juga menggunakan grup serialisasi yang dapat Anda atur menggunakan penjelasan Paparan pada bidang entitas, jangan lupa untuk melampirkan penjelasan Tabel ke entitas dan tentukan tabel alias, lebih baik menggunakan yang biasa Anda tentukan.
Contoh Pembuatan 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();
Akibatnya, SQL berikut akan dihasilkan:
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
Hasil:
[{"id": 3, "name": ", , 31", "advert_groups": [{"id": 10, "name": "avito-1115362430"}]}]
Ringkasan
Instruksi lengkap untuk digunakan akan segera ditambahkan ke repositori github. Akibatnya, ketika saya mengacaukan ini dalam proyek saya, saya menerima jawaban yang sangat cepat dari REST API dan pada saat yang sama saya dapat mengembalikan banyak objek dengan banyak dependensi bersarang, misalnya, apa yang ingin saya dapatkan melalui JMSSerializer yang saya dapatkan selama 40 detik, sekarang untuk 230 milidetik, dan ini asalkan Kernel Subscriber membaca anotasi pada bidang entitas melalui refleksi, saya ingin mengimplementasikan ini segera melalui cache Symfony.
Artikel ini akan dilengkapi ...
Bagian kedua