LINUX.ORG.RU

Web-фреймворки: где есть и как реализована (и как называется) «мультипроектность»?

 ,


0

2

Задача примерно такая.

Есть отдельные проекты (решения/приложения — кто как называет, у меня — проекты). Скажем (примеры от балды, небольшая гипертрофия):
— common — работа с единой базой пользователей, ряд общих для всех объектов и т.п.
— books — коллекция книжек
— books/admin — админка книжек
— films — коллекция фильмов
— films/admin — админка фильмов
— ad — рекламная система

Все проекты — разные репозитории (работают разные команды). При этом все проекты имеют доступ к объектам common и ad, books/admin позволяет обращаться к объектам books, но не наоборот и не к объектам films и т.п.

Если непонятно, уточню, спрашивайте.

У меня сейчас сделано так. Каждый проект — отдельный каталог/репозиторий с цельной структурой, принятой во фреймворке. Даже, скажем, books/admin — находится в том же репозитории, что и books, но в отдельном подкаталоге с полной структурой.

В конфигурации/загрузчике каждого проекта указано, какие проекты мы подключаем при просмотре/поиске объектов.

Контроллер фреймворка, получив задание найти объект, пересматривает зарегистрированные проекты в поисках подходящего класса и грузит его.

Все примеры популярных фреймворков демонстрируют решения «одна система — один проект». Соответственно, не могу даже оценить наличие таких возможностей в других фреймворках, не то, чтобы посмотреть, как сделано у них :)

Как с этим в популярных движках?

★★★★★

Последнее исправление: KRoN73 (всего исправлений: 1)

drupal - не чистый framework, а CMF
многопроектность называется multisit(e/ing)
есть дир с общими модулями для всех сайтов, + каждый сайт может иметь модули в своём персональном дире

Контроллер фреймворка, получив задание найти объект,
пересматривает зарегистрированные проекты в поисках подходящего класса и грузит его.

в друпале примерно так-же, только нет ООП, ну и модель соответственно не MVC

q11q11 ★★★★★
()
Ответ на: комментарий от q11q11

есть дир с общими модулями для всех сайтов, + каждый сайт может иметь модули в своём персональном дире

Вопрос именно в том, можно ли для каждого сайта указать, компонентами каких сайтов они могу пользоваться, а какими — нет?

KRoN73 ★★★★★
() автор топика

делаешь ядро в виде disfiles или phar - остальное логика проекта ссылающегося на distfiles. Но лучше, чтобы у каждого проекта все свое - только общие дистры либ. Или делаешь билд на каждый деплой.

swwwfactory ★★
()
Ответ на: комментарий от KRoN73

можно ли для каждого сайта указать, компонентами каких сайтов они могу пользоваться, а какими — нет?

каждый сайт предполагает отдельный домен,
все однозначно пользуются общими модулями,
при этом друг другом никто явно не пользуется,
но если знать физическую структуру системы - инклудами можно подкрутить,
только смысла в этом не очень много
проще модуль перенести в дир с общими модулями и включить его в админке,
ну или на крайняк скопировать в дир другого сайта

q11q11 ★★★★★
()
Ответ на: комментарий от RedPossum

А что вы имели в виду под поиском объектов/классов?

Скорее, PHP и т.п. заморочка. В Java это решается через CLASSPATH, так что это касается систем, где аналога списка каталогов, где искать классы нет. Ну и касается не только классов, но и иных ресурсов, тех же шаблонов.

KRoN73 ★★★★★
() автор топика

В Mojolicious можно монтировать отдельные аппликейшны в точки роутинга (но это, кажется, немного не то, что ты хочешь)

Второй вариант - делать bundle с контроллерами и прочим, и плагином, добавляющим неймспейс в путь поиска (можно и руками в аппликешне, но зачем?).

iSage ★★★★
()

В Django есть нечто подобное.

tyler19
()
Ответ на: комментарий от trashymichael

и пропатчить быстро можно, божеупаси, и обновлять удобней и безопасней

trashymichael ★★★
()
Ответ на: комментарий от trashymichael

лучше копировать в каждый проект отдельную копию фреймворка

Это, как раз, ни разу не проблема. Вопрос именно во взаимодействии между разными проектами.

так версионирование удобней

Как введение копий фреймворка улучшает версионирование? Как раз, центральный его репозиторий версионирование и упрощает :)

KRoN73 ★★★★★
() автор топика
Ответ на: комментарий от trashymichael

А чем плох центральный общий репозиторий для ядра фреймворка?

...

В любом случае, это не вопрос. Можно общий делать, можно свой для каждого проекта. Вопрос во взаимодействии проектов, объединении их в общую структуру.

KRoN73 ★★★★★
() автор топика

В есоде напр. используется технология подсайтов: - сайт определяет собственный типы данных и модели и т.д. - для «обратной» связи «сообщает» какие функции надо доопределить корневому сайту, + возможна реализация «по-умолчанию».

http://www.yesodweb.com/book/creating-a-subsite

хотя зачем я это тут пишу..

qnikst ★★★★★
()

— common — работа с единой базой пользователей, ряд общих для всех объектов и т.п. — books — коллекция книжек — books/admin — админка книжек — films — коллекция фильмов — films/admin — админка фильмов — ad — рекламная система

В Yii два основных способа сделать это:

1. Через модули основного приложения с одним front controller'ом.
2. Через несколько приложений имеющих как общую, так и личную кодовую базу. Уже с несколькими front controller'ами (можно даже по серверам раскидать).

Подробнее, если заинтересовало:

https://github.com/clevertech/YiiBoilerplate
http://www.yiiframework.com/wiki/33/organize-directories-for-applications-wit...

resurtm ★★★
()
Ответ на: комментарий от trashymichael

ну взаимодействие сайтов это уже другой вопрос имхо, типа общей базы пользователей и т.п.?

Не просто общей базы — а общих классов для работы с базой.

Ну, совсем простой вариант, для иллюстрации.

Вот есть http://www.balancer.ru — персональный сайт. Совсем простенький. Отдельный проект, отдельный репозиторий.

Есть http://forums.balancer.ru — корневая страница отдельного проекта форумов. Тоже отдельная сущность.

— Первый для вывода записей блога дёргает классы второго постингов форума с пометкой «is_blog».
— Второй в качестве родительской страницы в хлебных крошках (они полностью автоматические) использует ссылку на http://www.balancer.ru/, соответственно, загружает объект класса «balancer_main» для извлечения краткого имени в хлебных крошках.

Отдельные проекты, которые нет смысла смешивать в одном репозитории, но они пользуются объектами друг друга.

Или тот же сайт фреймворка, http://bors.balancer.ru — он тоже лезет и на форумы за новостями, и на balancer.ru за корневой страницей.

Это очень простые примеры, которые, понятно, можно при желании обойти простым дублированием некоторых сущностей. Но есть и куда более сильное смешивание. Скажем, http://www.aviaport.ru/ и его админка. Из основного сайта не нужен доступ к объектам админки. Хотя бы из соображений безопасности. Админка, наоборот, получает полный доступ ко всем объектам сайта. По сути — это два разных репозитория в рамках одного проекта (на самом деле три — общие классы, классы только сайта, не нужные админке, те же индексные страницы и, собственно, админка). А есть ещё посторонние проекты для третьих сторон, типа http://news.aviasalon.com/ — они на том же хостинге пользуются объектами того же АвиаПорта. Фактически, такие мелкие сайты, работающие на готовых объектах, делаются на коленке в считанные килобайты кода, львиную долю которых занимает альтернативная вёрстка, собственный код измеряется часто единичными строками.

А вот если каждый репозиторий автономен, то начинается каша. Поменял что-то в БД — не забудь тут же проверить и обновить все связанные проекты. По-одному, вручную. Объём работы на порядок возрастает.

KRoN73 ★★★★★
() автор топика

А почему бы не использовать для таких целей плагины вместо проектов? В симфони в плагине могут быть свои конфиги, схема, контроллеры и при этом его можно подключить к любому проекту парой строк в конфиге и оно будет использовать бд именно этого проекта если не указано обратное.

Tark ★★
()
Ответ на: комментарий от Tark

А почему бы не использовать для таких целей плагины вместо проектов?

А чем по сути плагин отличается от класса модели + вьюхи? :)

Всё равно возникает вопрос совместной работы.

Более того, скажем, модель-то в разных проектах будет одной, а вот представление может сильно отличаться. На объектной системе такое делается элементарно, через наследование (при чём с новыми шаблонизаторами даже с наследованием не только классов, но и шаблонов), а вот наследование плагинов — это что-то непонятное :)

KRoN73 ★★★★★
() автор топика
Ответ на: комментарий от iSage

В Mojolicious можно монтировать отдельные аппликейшны в точки роутинга (но это, кажется, немного не то, что ты хочешь)

+1. ЕМНИП, называется «nested apps».

helios ★★★★★
()
Ответ на: комментарий от KRoN73

Тем, что все вьюхи, контроллеры и модели плагина можно наследовать и изменить в своем приложении, и тем, что схему БД оно носит с собой? Плагин это просто директория как бы с инсталляцией фреймворка, но без фреймворка внутри и только с локальными конфигами(значения в которых имеют меньший приоритет чем значения в конфигах проекта) и прочим.
А вообще насчет моделей. Зачем городить этот огород из моделей, разве не проще это сделать написав простенький REST апи?

Tark ★★
()
Ответ на: комментарий от Tark

А вообще насчет моделей. Зачем городить этот огород из моделей, разве не проще это сделать написав простенький REST апи?

Потому что работа с моделью занимает в несколько раз меньше кода. Фактически, по одной операции на почти что угодно.

Я уже не говорю о том, что REST внутри одного проекта — это же будет страшный оверхед. Во что превратится загрузка тысячи объектов по REST?

KRoN73 ★★★★★
() автор топика
Ответ на: комментарий от KRoN73

Потому что работа с моделью занимает в несколько раз меньше кода. Фактически, по одной операции на почти что угодно.

Зато безопасность либо нулевая, либо для каждого проекта нужно городить огород из пользователей SQL с правами и разбивать таблицы.

Я уже не говорю о том, что REST внутри одного проекта — это же будет страшный оверхед. Во что превратится загрузка тысячи объектов по REST?

С одной стороны да, но с другой стороны REST не запрещает отдавать коллекции с какими-то условиями. Зачем грузить тысячи объектов по REST в таком случае?

Tark ★★
()
Ответ на: комментарий от KRoN73

Т.е. основная проблема это постоянные изменения в структуре баз и зависимость общих классов по работе с БЛ и данными БД?

на уровне кода, сложность управления совместной кодовой базой в смежных проектах можно понизить через git subtree.

Мне кажется, тебе нужно еще большее разделение слоев. Причем выпилить ядро, общее для всех проектов, включая админку.

Касаемо классов БД - выделить «локальную БЛ» для каждого проекта, остальное: тоже в общее ядро.

Насчет синхронизации структур БД. У тебя базы по проектам разные или одна?

swwwfactory ★★
()
Ответ на: комментарий от Tark

Зато безопасность либо нулевая

Если у тебя есть доступ к коду проекта, а у кода проекта есть доступ к БД, то безопасность тут одинаковая выходит.

Зачем грузить тысячи объектов по REST в таком случае?

Например, если тебе нужна хитрая клиентская сортировка. Или реально нужна вся тысяча — например, экспорт списка клиентов в XLS. Кстати, вполне практическая задача. Есть отдельный (закрытый, потому без ссылки) проект, который использует привязки своих объектов к данным того же http://www.aviaport.ru. И, вот, в этом закрытом проекте интенсивно используется экспорт в XLS данных с АвиаПорт'а в больших объёмах.

KRoN73 ★★★★★
() автор топика
Ответ на: комментарий от KRoN73

Если у тебя есть доступ к коду проекта, а у кода проекта есть доступ к БД, то безопасность тут одинаковая выходит.

Ну если данными меняться только по REST, то доступа к БД не будет.

Например, если тебе нужна хитрая клиентская сортировка. Или реально нужна вся тысяча — например, экспорт списка клиентов в XLS. Кстати, вполне практическая задача. Есть отдельный (закрытый, потому без ссылки) проект, который использует привязки своих объектов к данным того же http://www.aviaport.ru. И, вот, в этом закрытом проекте интенсивно используется экспорт в XLS данных с АвиаПорт'а в больших объёмах.

Ну даже в таком случае, скорость доступа к REST апи будет в несколько раз выше чем передача этих данных клиенту, так что в нее не упрется особо.

Tark ★★
()
Ответ на: комментарий от swwwfactory

Т.е. основная проблема это постоянные изменения в структуре баз

Нет. Это только одна и относительно нечастая из проблем :) Самые частые проблемы — мелкие изменения в модели, часто не затрагивающие БД.

и зависимость общих классов по работе с БЛ и данными БД?

В идеальном программном проекте не должно быть копипаста. Не должно быть повторяющихся блоков. Если несколько сущностей могут работать унифицированно с одним кодом, то они должны так делать. Thinking Forth :)

в смежных проектах можно понизить через git subtree

Подразумевается, что репозитории вообще независимы. Они могут принадлежать совершенно разным проектам, не имеющих прямого отношения друг к другу.

Собственно, у меня даже основной фреймворк состоит из трёх независимых репозиториев. bors-core — ядро системы плюс основные, часто используемые компоненты. В принципе, там до сих пор довольно много мусора, который стоит вынести в следующий, но дело низкоприоритетное bors-ext — разные расширения, которые могут использоваться не во всех проектах, часто вообще не нужны. Зачем, скажем, на сайте авиационных новостей парсинг bb-кода или работа Яндекс.Видео bors-third-party — монстр с десятками мегабайт всяких jQuery/PEAR/Smarty и т.п. плюс обвязка по их использовнаию. Чтобы разворачивая очередной хостинг не ломать голову о скачивании и подключении всего этого зоопарка. Но если с местом напряжёнка (хотя в последние годы это уже давно не вопрос), то можно и вручную подтянуть только то, что надо.

Причем выпилить ядро, общее для всех проектов, включая админку

Ядро выпилено очень давно. Фактически, нынешний репозиторий (сам-то проект куда как древний) начался именно с выпиливания ядра. А вот админки — они, как раз, обычно у всех проектов свои.

Насчет синхронизации структур БД. У тебя базы по проектам разные или одна?

Так от проектов зависит :) Понятно, что есть совершенно независимые проекты. Есть проекты, использующие общий код, но разные БД. Есть проекты, работающие с общими БД. Рождается пара проектов с межхостовым/межпроектным обменом объектами в переносимом формате (JSON), но там пока всё в долгом ящике.

Мне кажется, тебе нужно еще большее разделение слоев

Вообще, сейчас в каждом проекте есть обычно четыре слоя (четыре набора каталогов, репозиториев общей структуры). Три перечисленных слоя ядра фреймворка + собственно локальный репозиторий проекта. И в случае смешения ещё можно указывать каталоги других проектов, из которых берутся общие компоненты.

На уровне кода всё определяется дефайнами в загрузчике. Загрузчик (точка входа) выглядит обычно так:

<?php
define('BORS_CORE', '/var/www/bors/bors-core');
define('BORS_SITE', '/var/www/bors/bors-aviaport/sites/admin.aviaport.ru');
define('BORS_APPEND', '/var/www/bors/bors-aviaport /var/www/bors/bors-aviaport-old  /www/sites/bors/aviaport-common');

require_once(BORS_CORE.'/main.php');

Т.е. обычно надо указать путь к ядру (оно где угодно может быть, естественно, и в R/O, хоть в /usr), путь к репозиторию сайта и дополнительные репозитории.

В данном случае точка входа фреймворка по BORS_CORE ещё сама определит BORS_EXT и BORS_3RD_PARTY — вторые каталоги собственно фреймворка, они обычно лежат на том же уровне, что и bors-core, так что явно указывать нет надобности.

KRoN73 ★★★★★
() автор топика
Ответ на: комментарий от Tark

Ну даже в таком случае, скорость доступа к REST апи будет в несколько раз выше чем передача этих данных клиенту, так что в нее не упрется особо.

В этом случае — да. В общем случае снижение скорости будет слишком большим.

Вообще же, надо подумать. Теоретически работа с REST может быть включена прозрачно, без переписывания кода. Загрузчики объектов работают с любым бэкендом и таким бэкендом может быть REST. С точки зрения разделения проектов пользы нет, так как всё равно вознкнет вопрос унификации, теперь уже REST-моделей.

Но зато можно будет прозрачно обеспечить межсайтовую работу. Сейчас-то я для этого дёргаю JSON в явном виде, почему-то не подумал, что REST-бэкенд можно просто задействовать.

KRoN73 ★★★★★
() автор топика
Ответ на: комментарий от KRoN73

В этом случае — да. В общем случае снижение скорости будет слишком большим.

Снижение скорости будет значительным. Но не таким значительным, каким оно кажется, потому что от сервера до сервера пинги гораздо меньше, чем от сервера до локального компа.

С точки зрения разделения проектов пользы нет, так как всё равно вознкнет вопрос унификации, теперь уже REST-моделей.

К REST моделям проще приделать безопасный ACL.

Tark ★★
()
Ответ на: комментарий от KRoN73

Нет. Это только одна и относительно нечастая из проблем :) Самые частые проблемы — мелкие изменения в модели, часто не затрагивающие БД.

Что мешает тогда эти мелкие изменения локализовать и завернуть в отдельные слои?

Подразумевается, что репозитории вообще независимы. Они могут принадлежать совершенно разным проектам, не имеющих прямого отношения друг к другу.

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

В идеальном программном проекте не должно быть копипаста. Не должно быть повторяющихся блоков. Если несколько сущностей могут работать унифицированно с одним кодом, то они должны так делать. Thinking Forth :)

Согласен - копипаста зло. С этим из разных проектов борюсь в основном через подмонтирование субтри или вынесением общих сущностей в ядро.

Thinking Forth :)

Разумеется. Стэк-машина рулит. Альтернатива именованию сущностей ))

В данном случае точка входа фреймворка по BORS_CORE ещё сама определит BORS_EXT и BORS_3RD_PARTY — вторые каталоги собственно фреймворка, они обычно лежат на том же уровне, что и bors-core, так что явно указывать нет надобности.

это разумно

swwwfactory ★★
()

В рельсах неплохо в виде mountable engines.

drakmail ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.