У меня есть веб-приложение, построенное на PHP (Symfony 3) и MySQL (Doctrine).
Все это работает хорошо, и теперь я хочу создать REST API, чтобы сделать некоторые части данных приложения общедоступными.
Для упрощения, скажем, у меня есть страница / products , а для каждого продукта - страница подробностей / product / {id} .
На странице продуктов пользователи могут применять несколько фильтров к списку продуктов, например, какие категории они хотят.
Большинство фильтров - это просто список флажков, которые пользователь может выбрать (без текстовых фильтров).
Таблица продуктов имеет много связей, хотя она не была чрезмерно нормализована; это присуще домену, с которым я работаю.
Чтобы получить все данные для одной строки продукта, мне нужно сделать + - 20 объединений по 15 отдельным запросам.
Да, я знаю, что это много, но большинство таблиц - это просто простые таблицы поиска, а общее время запроса занимает всего + - 3 мс.
Фильтрация списка продуктов осуществляется с помощью построителя запросов SQL.
Поскольку на странице продуктов отображается только список названий продуктов, производительность здесь не проблема.
Но вот в чем проблема: REST API должен будет сгенерировать список полных объектов продукта со всеми данными (не только именами).
Как вы можете себе представить, фильтрация + все дополнительные объединения / запросы и GROUP BY не очень хороши для производительности.
Чтобы решить эту проблему, я думал о создании какой-то гибридной системы, используя только SQL для записи обновлений в базу данных и сохраняя хранилище документов, предназначенное только для чтения, для извлечения продуктов из.
Самая простая реализация, о которой я могу подумать, это создать таблицу product_api_cache , в которой хранятся продукты, сгенерированные как JSON, готовые для отображения в API.
Если пользователь запрашивает ресурс / api / products , построитель запросов применяет фильтры для возврата списка идентификаторов продуктов, которые затем можно использовать для получения JSON продуктов из product_api_cache таблица.
Более продвинутой реализацией было бы использование подходящего хранилища документов, такого как ElasticSearch или MongoDB.
Я не уверен, как это будет соответствовать текущей системе фильтрации (построитель SQL-запросов).
Значит ли это, что мне нужно продублировать всю логику фильтрации специально для ElasticSearch?
Кроме того, JSON, который должен возвращать API-интерфейс, не на 100% соответствует реальному объекту продукта (он значительно упрощается за счет его сериализации).
Значит ли это, что мне нужно написать 2 отдельных слоя сериализации? Первый для хранения версии объекта JSON 1-на-1, чтобы ElasticSearch мог правильно запросить его, а затем второй для сериализации результата ElasticSearch в упрощенное для пользователя представление.
Поскольку ElasticSearch возвращает JSON, означает ли это, что мне нужно десериализовать этот результат в объект продукта, чтобы затем снова сериализовать объект продукта?
Какой разумный способ реализовать это? Есть ли еще способы сделать это? Думаю ли я что-то не то?