Документация/Контроллеры/Модуль

Модуль

Модульный подход в программной архитектуре позволяет логически разделить проект на крупные составные фрагменты (модули). Показателем модуля является его самодостаточность, в некотором смысле - это разделение на "микросервисы" внутри монолитного приложения.
Основные отличия от микросервисов состоят в том, что модули должны обмениваться данными через определенные контракты, заменяющие собой HTTP API (или брокер сообщений), а также используют общую папку с маршрутами, сервисы и внешние библиотеки из папки /vendor/. Контракты рекомендуется составить таким образом, чтобы они позволяли при необходимости выделить модуль в полноценный микросервис.

Во фреймворке HLEB2 подразумевается, что Модуль представляет собой MVC (Action-Domain-Responder для веб) в миниатюре. У модуля есть свой контроллер, своя папка с шаблонами, даже своя конфигурация допустима, это всё находится внутри папки с модулем. Своя логика тоже подразумевается (как и Модели), но для этого рекомендуется создать отдельную структуру в папке /app/ проекта или в самом модуле.

При использовании подхода полной автономности частей в проекте, в чем и заключается применение модульной разработки, можно не использовать совсем контроллеры, middleware и модели из /app/, реализовав всё в модулях.

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

use Modules\Example\Controllers\ExampleModuleController;

Route::any('/demo-module')->module('example'ExampleModuleController::class, 'index');

Контроллер модуля должен быть унаследован от Hleb\Base\Module.

Для того чтобы загрузчик классов Composer составил карту классов для модулей, добавьте в раздел "autoload" > "classmap" файла /composer.json строчку с названием папки модулей ("modules/").


#Создание модуля

Простой способ создания базовой структуры модуля через консольную команду:

$php console --create module example

Эта команда создаст новый шаблон модуля в директории /modules/example/ проекта. Можно использовать другое подходящее название для модуля, состоящее из латинских букв в нижнем регистре, цифр, дефиса и символа '/' (указывающего на вложенность). Есть возможность переопределить исходные файлы модуля, используемые при генерации.

Структура модуля после создания (если ранее не было папки modules, то консольная команда её создаст в корне проекта):

modules   - директория для модулей
     example   - папка модуля example
     ⊢ config
     |      ⊢main.php   - настройки модуля
     ⊢ controllers
     |      ⊢DefaultModuleController.php   - контроллер модуля
     ⊢ views
            ⊢example.php   - шаблон модуля

Файл main.php может содержать настройки, аналогичные файлу /config/main.php, но c используемыми только в модуле значениями, то есть будет их "перекрывать". Изначально файл main.php не содержит никаких настроек, используются все настройки из /config/main.php.
Подобным образом здесь могут быть заменены настройки файла /config/database.php созданием одноимённого файла. Настройки других конфигурационных файлов всегда действуют глобально.

Контроллер модуля аналогичен стандартному контроллеру фреймворка. При использовании в нём функции view() путь к шаблону будет указывать в папку 'views' модуля, как и для всех встроенных функций фреймворка для работы с шаблонами


#Вложенные модули

Существует возможность объединять модули в группы, вложенные в разные подпапки /modules/. Для этого модули размещаются уровнем ниже, а в название модуля добавляется название группы. Это составляет второй уровень вложенности модулей.

Представим, что необходимо разместить группу модулей под названием 'main-product', в ней будут модули 'first-feature' и 'second-feature'.

modules
 ⊢ main-product - группа модулей
     |
     ⊢ first-feature   - папка модуля first-feature
     |   ⊢ config
     |   |      ⊢main.php
     |   |      ⊢database.php
     |   ⊢ controllers
     |   |      ⊢ModuleGetController.php
     |   |      ⊢ModulePostController.php
     |   ⊢ views
     |          ⊢template.php
     |
     ⊢ second-feature   - папка модуля second-feature
         ⊢ controllers
         |      ⊢ModuleController.php
         ⊢ middlewares
         |      ⊢ModuleMiddleware.php
         ⊢ views
                ⊢template.php

Вот так это будет выглядеть в карте маршрутов:

use Modules\MainProduct\{
    
FirstFeature\Controllers\ModuleGetController,
    
FirstFeature\Controllers\ModulePostController,
    
SecondFeature\Controllers\ModuleController,
    
SecondFeature\Middlewares\ModuleMiddleware,
};

Route::get('/demo-group-module/first')
    ->
module('main-product/first-feature'ModuleGetController::class);

Route::post('/demo-group-module/first')
    ->
module('main-product/first-feature'ModulePostController::class);

Route::any('/demo-group-module/second')
    ->
module('main-product/second-feature'ModuleController::class)
    ->
middleware(ModuleMiddleware::class);

В группе под названием 'first-feature' присутствует переназначение настроек, в том числе для баз данных.
Пример для 'second-feature' использует глобальные настройки, дополнительно у него есть middleware к контроллеру. Возможно, что там могут появиться ещё контроллеры.

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


#Название папки с модулями

Изначально папка с модулями называется 'modules', до создания модулей можно изменить это название в настройках, например на 'products'.
Делается это в файле /config/system.php - настройка 'module.dir.name'. Если изменение производится с уже существующими классами модулей - необходимо исправить namespace модулям, которые по PSR-0.


#Переопределение настроек

В модуле могут быть переопределены два файла конфигурации - /config/main.php и /config/database.php.
Переопределяются значения параметров по ключу рекурсивно, иначе параметр имеет глобальное значение. Новые параметры, не имеющие глобального аналога, будут доступны локально в модуле.


#Пути к шаблонам в модулях

При использовании модулей как отдельных пакетов, не всегда нужно, чтобы в пакете были шаблоны View, так как оформление и вывод результата может быть отдельным слоем в структуре приложения.
Поэтому, может быть два варианта использования шаблонов. Под "использованием" подразумеваются как указатели на шаблоны в функции view(), так и в специальных функциях вида insertTemplate().

Если в модуле есть папка /views/, то пути шаблонов будут указывать в неё.
Но если такой папки нет, то поиск шаблона будет происходить в директории /resources/views/ проекта.

Контроллер Middleware

Страница создана: @fomiash
К началу страницы