Pull to refresh
47
0

Пользователь

Send message

Всё верно, блоги+пользователи это один-к-одному, а телефоны+оценки+X+Y+Z это и есть один-ко-многим, поэтому и разделяем. Вот и приходится извращаться денормализацией и отдельными запросами. Да, проблема именно в том, что result set слишком большой, даже если в итоге всего 10 постов на странице

Контроллер возвращает не JSON. Контроллер возвращает Response (JsonRespose, извините что я опять про симфони).

правильно я понимаю, что если у меня есть PostSerializer, но нет PostController, то я должен реквест закинуть в PostSerializer, ведь результат будет одинаков? Кто первый тот и отдает json?
Одно и то же повторяю разными словами по кругу.


Если у вас по какой-то неведомой причине PostSerializer возвращает объект Response, то да. Но очевидно что это не так, поэтому реквест надо закидывать в PostController.
а в чем у вас проблема с этим? вообще понятие сервисов (не сервисов симфони) сервисного слоя вам знакомо?


У меня как раз с этим никаких проблем нет :)) Есть механизмы, отвечающие за извлечение записей из БД, есть механизмы, отвечающие за проверку прав. Вы повысили уровень абстрации, объединив их в один механизм, который назвали postService.
Мы явно говорим на разных языках. Я не хочу переходить на личности, но посоветовал бы почитать книг вообще по архитектуре приложений, какие-нибудь энтерпрайз шаблоны Фаулера, ДДД Эванса. В вас чувствуется «специалист одного фреймворка», обосновывающий все конкретной реализацией, а не логичностью.


Что ж, на этом и предлагаю закончить эту увлекательную дискуссию. Благодарю.

Контроллер генерит респонс. Он занимается только этим. В чём вопрос?

Кажется, я понял в чем ваше затруднение. Вы зачем-то наделяете вещи (контроллеры, сервисы) знаниями о том, кто, откуда и зачем их вызывает. Они не должны этого знать. Контроллеру должно быть всё равно, откуда он вызывается. Ему дают аргументы (реквест, объект, что угодно) и он на основании этих аргументов строит респонс. Его не должно волновать, вызывается он функцией из вью, из kernel или ещё откуда-то.


Конечно, сервис $postService имеет право на жизнь, но не проще ли воспользоваться уже готовым кубиком voters? Соединяем repository+voter+controller и получаем ваш postService. SOLID говорите? Ну-ну. И достать, и права проверить...


И я понял как вы решаете эту проблему. Вы просто делаете более высокоуровневую надстройку над фреймворком, чтобы вам было удобнее. Увеличиваете размер кубиков. Что ж, такая стратегия имеет право на жизнь, но тогда почему симфони? Почему не Yii или не битрикс с вордпрессом? Там это уже в готовом виде.

Кстати, вот подумал, если вам очень хочется иметь компоненты (мне тоже хотелось, когда я слезал со своего велосипедного фреймворка на симфони), то их можно реализовать с помощью всё тех же мастер-реквестов. Ну и психологическую обёртку над render(controller(...)), например, render_component('sidebar') :)

Контроллер это тоже часть некой системы, и в чем отличие от компонента? Реквест — это всего лишь аргумент контроллера (он там может быть, а может и не быть).
$postService->findById($id) — возвращает Post
$postRepository->findById($id) — возвращает Post


Вот смотою и туплю, а зачем нужен $postService? Есть же репозиторий для этих целей.
Должен быть компонент, рендерящий вьюшку на основе клиентского реквеста. Должен быть компонент, рендерящий часть вьюшки для реюзабельности. Две ответственности — два компонента.


Оба на входе принимают аргументы, а на выходе — респонс для вью, и в этом заключается их ответственность, которая одинаковая в обоих случаях. Симфони не стал делить контроллеры на внутренние/внешние, вложенные/невложенные, с реквестом/без него. Контроллер должен выдать респонс. Если тебе нужен респонс, то обращайся к контроллеру. Всё остальное — повышение уровня абстрации.

И да, в симфони также нет такого понятии как "страница", "вложенная структура" и т.п. Есть контроллеры, есть роуты, есть шаблоны. Все эти дополнительные абстракции, которые делают фреймворк более высокоуровневым, присущи другим продуктам, типа Yii. Вероятно, они даже в некоторых местах делают разработку удобнее. Но всё же, если нужен блог, то решения лучше вордпресса не найти. Симфони2 удивительный фреймворк. Он задаёт стандарты, предоставляя при этом чрезвычайно маленькие и несвязанные кубики. В Yii-подобных этого даже близко нет и не предвидится. Монолит, чрезвыйчайно кастомизируемый и чуть более современно написанный битрикс.

Да поймите же, что в симфони2 нет разницы между компонентом и контроллером. И незачем её искусственно создавать. Во всех случаях, когда нужно проконтролировать генерацию вью, используются контроллеры. Частично или полностью, с урлом или без — это вы всё решаете каждый раз в частном порядке. Да, может быть в других системах штуки для генерации вью под названием "layout" называют "контроллерами", а штуки под названием "sidebar" называют компонентами. В симфони2 пошли другим путём. Контроллер контролирует генерацию вью. Если какому-то вью требуется для своего рендера другой вью, который контролируется кем-то, то он обращается к тому, кем оно контролируется, т.е. к контроллеру.

Все-таки не понимаю зачем вам нужна ещё одна структура под названием "компонент". Просто для того, чтобы показать, что она не самостоятельная структура, а вложенная? Ну называйте контроллеры SidebarComponent и всё :)

А если вам понадобится контроллер, который может быть доступен по урлу и может быть вставлен в виде "виджета", вы что будете делать? Ну например, форма логина, которая может быть в модальном окне и в body страницы, в зависимости от ситуации. Тут-то ваша "компонентная" логика и поломается.

Контроллер не обязан рендерить всю страницу, не пойму откуда этот стереотип. Он рендерит только то, за что отвечает (чаще всего — действительно за всю страницу целиком, но это не догма). И смысл разбиения страницы на несколько контроллеров — это делегирование ответственности.
Опять же протечка слоев — слой вьюшки запрашивает сущность из слоя контроллеров, хотя должно быть наоборот.


Вот именно. Вью говорит — у меня тут должен быть сайдбар, я хз что там за данные, нужны ли обращения к БД или не нужны, но вот ОН (контроллер) точно знает. Поэтому я сюда вставлю то, что ОН мне респонсит.

Озвученная причина несостоятельна. А вот с lazy load прикол (проблема) в том, что при больших количествах зависимостей между выбираемыми сущностями иногда бывает быстрее (даже в продакшене) использовать единичные доп.запросы. Потому что гидрация данных начинает сжирать какое-то невероятное время. И бывает быстрее выбрать только блоги+пользователей, а потом маленькими быстрыми запросами дополнить их телефонами+оценками+Х+Y+Z, чем выбрать сразу всё одним запросом…

Ну вы же понимаете, что это не показательно… Быстрее в 4 раза? Дело однозначно не в контроллере/твиг-функции, там просто неоткуда взяться такой разнице. Скорее всего вас с контроллерами что-то не то. Если у вас висят обработчики на события реквеста, проверьте, нужны ли они на ВСЕ реквесты, или же стоит ограничиться мастер-реквестами. Почти уверен, что дело в этом.

В симфони2 нет компонентов. Есть только контроллеры, которые получают реквест и выдают респонс. Компонент делает ровно то же самое — на входе название компонента (урл), на выходе респонс (html), тогда вопрос: чем компонент отличается от контроллера, и коль уже есть контроллер, то зачем нужен некий компонент? В симфони1 существование компонентов было оправдано тем, что они типа более легковесные, там не проверяются права и т.п. В симфони2, видимо, посчитали этот аргумент слишком незначительным, ну или были какие-то другие причины, я не знаю. При таком решении компонент-контроллер становится более независимым, а значит, более реюзабельным и тестируемым.

render(component(...)) это и есть вызов контроллера для получения некого ресурса. Да, у этого ресурса нет внешнего урла (а может и есть, никто не запрещает). Но он точно так же может работать с реквестом, с контейнером, генерить какие-то данные и выдаёт какой-то респонс. И это именно то, что требуется в сайдбаре. Получить ресурс "данные для сайдбара" — задача более подходящая для контроллера, нежели для твиг-функции (которая вобще-то не должна делать ничего, кроме обработки и подготовки к выводу уже поступивших данных, а тут она в БД полезет, начнёт с моделью работать).

Измеряли, само собой, в prod? Каким образом? "Гораздо быстрее" — это насколько в процентах?


Кстати, говорят, на голом пхп ещё быстрее страницы рендерятся. Но фреймворк не только и не столько для скорости исполнения кода придуман. Если есть какая-то отделяемая многократно используемая часть шаблона, то для этого можно и нужно использовать render(controller(...)). А не наделять вью (да-да, кастомная функция твига это вью) несвойственными ей полномочиями.

Очевидно, с такой позицией начнётся драка. У меня есть желание бить по рукам тем, кто запрещает такое по неведомым причинам.

Красиво — на мой взгляд, с помощью knp_pagination. Доктрина1 умела самостоятельно делать то, что вы от неё ожидаете, доктрина же вторая, видимо, пошла более нативным путём. К тому же никто не мешает реализовать свой with() для доктрины.

Бред какой-то по ссылке. Даже комментировать не хочется. Не знаю кто автор, но это у него в голове сплошные дырявые абстракции.

Точно! Распространённые грабли, в том числе среди не новичков. Поясню для тех, кто знакомится с ними впервые: чтобы получить то, что требуется ($limit блогов с комментариями), нужно сначала (отдельным запросом) выбрать айдишники нужных блогов в количестве $limit штук, а потом (вторым запросом) выбрать блоги, комментарии к ним и всё что ещё потребуется, используя ->andWhere('b.id IN :blogs_ids'), при этом не используя ни setMaxResults, ни всякие andWhere. Бандл knp_paginator берёт эту рутину на себя, его можно использовать не только для пагинации.

и имеющим одинаковую подпись

signature это не подпись, это сигнатура. Список в конце забыли перевести? Перевод читается трудно, т.к., видимо, был сделан без понимания сути.

Information

Rating
Does not participate
Registered
Activity