Всем привет Разрабатываю админку для АТС. Дошел до "Настроек". Роуты API планируются следующие /api/pbx/trunks - внешние линии /api/pbx/dev - устройства /api/pbx/audio - голосовые файлы /api/pbx/ivr - голосовые меню ...ну и еще с десяток разделов создал модель и контроллер php artisan make:model PBX php artisan make:controller PBXController Подскажите пожалуйста - как "разбить" большой контроллер на мелкие ? Правильно-ли я мыслю, что надо в app/Http/Controllers создать папку PBX и в ней держать файлы TrunksController.php DevController.php AudioController.php IvrController.php .... Не могу понять - как их теперь правильно зацепить в имеющийся app/Http/Controllers/PBXController.php
Тут нет единственно верного подхода. Что-то очень мало у тебя маршрутов и всего одна модель. А ты уже что-то разбивать собрался. В разбивке и группировке я бы танцевал от данных: прикинул какие таблицы нужны, разбил бы их на несколько групп по функциональной близости, как например так: Таблицы User, Department, Group, Role, Permission - это группа User Category, Board, Thread, Message - группа Communication и т.д. На каждую группу создал бы как минимум по сервису (или репозиторию) цель которого спрятать реализацию и предоставить методы кроме CRUD в едином стиле. Некоторые сервисы могут быть завязаны не на таблицы (не только на них), а на функционал или внешние API, например. Типа файловый сервис, который скрывает он контроллера, что работает с Amazon S3 для примера. К сервисам будут обращаться контроллеры, это новый уровень группировки. Скорее всего контроллеров будет меньше, чем сервисов и гораздо меньше, чем моделей. В общем случае логично в маршрутах использовать префиксы, соответствующие контроллерам или сервисам. Типа /api/reports/... /api/products/... Когда 99% работы происходит вне контроллера, он начинает состоять в основном из спецификаций apidoc и правил валидации.
Так можно. Но я обычно против кучи контроллеров, в каждом из которых по одной акции. Особенно, если учесть, что при правильном написании в методе контроллера должно быть от 1 до 10 строчек, если больше 10 строчек, уже надо выносить в сервис. ПОэтому 10 методов по 1-10 строчек - вполне себе читаемый контроллер получается.
метода в 200 строк вообще не должно быть в системе, ни одного. Если требуемое действие реализуется в 20 строк, оно должно быть разбито на мелкие методы, строк 20-30 от силы. иначе это читать невозможно, не говоря уж о тестировании или отладке , Это у вас роут или префикс для группы роутов?
200 строк - это весь блок, ответственный за функционал (и геттеры и сеттеры) Сейчас файл pbx.conf - почти 4000 строк. Вот и пытаюсь его раздробить на разделы /api/pbx - это префикс группы
А я про 1-10 строк пишу - про нормальный размер одного метода контроллера, так что как одно с другим связано? А это что такое?
ну какие-то есть короткие методы, какие-то длинные. Сейчас конечно буду другой уровень абстракции закладывать Это существующая админка. Переделываю ее --- Добавлено --- Я пока не силен в Laravel и к сожалению не вижу всех подводных камней в разработке на нем Попытаюсь сформулировать хотелки Задача № 1 - переписать существующее API, чтобы оно позволяло управлять данными /api/pbx - префикс группы настроек /api/pbx/trunk - управления транками /api/pbx/trunk.list - показать все транки /api/pbx/trunk.get - получить один /api/pbx/trunk.update - обновить /api/pbx/trunk.delete - удалить /api/pbx/trunk.insert - добавить /api/pbx/dev - управления устройствами /api/pbx/dev.list - показать все устройства /api/pbx/dev.get - получить один /api/pbx/dev.update - обновить /api/pbx/dev.delete - удалить /api/pbx/dev.insert - добавить При этом из метода /api/pbx/dev надо иметь доступ к api/pbx/trunk, чтобы например проверить корректность привязки устройства к внешней линии Задача № 2 - натянуть на новое API новую тему
Может сначала стоит выучить? А то я говорю конкретно - контроллер, а вы о чём-то ещё пишите. Я спрашиваю, это роут или группа, вы говорите роут, а оказывается группа. --- Добавлено --- Я когда начинаю с новым фреймворком или CMS или технологией разбираться, я сначала от корки до корки читаю документацию, а потом лезу что-то писать
Это не очень хорошо. В REST принято действие (глагол) связывать с методом http, а не с адресом. То есть URL должен указывать на ресурс, например, Сообщение. Если по адресу обратиться методом POST это будет добавление, если PUT изменение, DELETE угадай что В Larsvel для упрощения работы с этим есть особый описатель маршрутов: redourse. Почитай об этом прежде чем делать. --- Добавлено --- Извини за рчепятки, я с мобилы пишу. Ломает исправлять.
Правильно-ли я делаю или это говнокод, хотя и рабочий на данном этапе ? Создал провайдера и прописал его в config/app.php Файл app/Providers/MainServiceProvider.php Код (Text): <?php namespace App\Providers; use Illuminate\Support\ServiceProvider; class MainProvider extends ServiceProvider { /** * Register services. * * @return void */ public function register() // Импортируем функции из app/Services/*.php { foreach (glob(app_path('Services') . '/*.php') as $file) { require_once $file; } } } В app/Services два файла Файл app/Services/ServiceA.php Код (Text): <?php namespace App\Providers\MainProvider\ServiceA; function index() { return [ "srvA #1","srvA #2", "srvA #3" ]; } function get( $id ) { $items = index(); if ( $id<1 || $id > count( $items ) ) { return false; } return ['id' => $id, 'name' => $items[ $id-1 ] ]; } ?> Файл app/Services/ServiceB.php Код (Text): <?php namespace App\Providers\MainProvider\ServiceB; use App\Providers\MainProvider\ServiceA as ServiceA; use Illuminate\Http\Request; function index() { return [ 'srvB #1', 'srvB #2', 'srvB #3']; } function get( $id ) { $items = index(); if ( $id<1 || $id > count( $items ) ) { return false; } return [ 'id' => $id, 'name' => $items[ $id-1 ] ]; } function post( Request $request ) { $id = $request->input('id'); $srvA_id = $request->input('srvA_Id'); if ( !ServiceA\get( $srvA_id ) ) { return [ 'id' => $id, 'srvA_Id' => $srvA_id, 'status' => 'Error - srvA not found' ]; } return [ 'id' => $id, 'status' => 'Update ok' ]; } } ?> Файл routes/api.php Код (Text): <?php use Illuminate\Http\Request; use App\Providers\MainProvider as MainProvider; Route::get('srvA', function () { $response = MainProvider\ServiceA\index(); return response( $response ,200); }); Route::get('srvA/{id}', function ( $id ) { $response = MainProvider\ServiceA\get( $id ); return response( $response ,200); }); Route::get('srvB', function () { $response = MainProvider\ServiceB\index(); return response( $response ,200); }); Route::get('srvB/{id}', function ( $id ) { $response = MainProvider\ServiceB\get( $id ); return response( $response ,200); }); Route::post('srvB', function ( Request $request ) { $response = MainProvider\ServiceB\post( $request ); return response( $response ,200); });
Ну если у вас всё в таком роде, возьмите Slim какой-нибудь, вам ларавеля много. А так, вынесете в классы хотя бы ваши сервисы, чтоб автолоадинг находил.
Получилось вот так Создал провайдера и прописал его в config/app.php Файл app/Providers/MainServiceProvider.php Код (Text): <?php namespace App\Providers; use Illuminate\Support\ServiceProvider; class MainProvider extends ServiceProvider { } В app/Services два файла Файл app/Services/ServiceA.php Код (Text): <?php namespace App\Providers\MainProvider; class ServiceA { public static function index() { return [ "srvA #1","srvA #2", "srvA #3" ]; } public static function get( $id ) { $items = ServiceA::index(); if ( $id<1 || $id > count( $items ) ) { return false; } return ['id' => $id, 'name' => $items[ $id-1 ] ]; } } ?> Файл app/Services/ServiceB.php Код (Text): <?php namespace App\Providers\MainProvider; use App\Providers\MainProvider\ServiceA as ServiceA; use Illuminate\Http\Request; class ServiceB { public static function index() { return [ 'srvB #1', 'srvB #2', 'srvB #3']; } public static function get( $id ) { $items = ServiceB::index(); if ( $id<1 || $id > count( $items ) ) { return false; } return [ 'id' => $id, 'name' => $items[ $id-1 ] ]; } public static function post( Request $request ) { $id = $request->input('id'); $srvA_id = $request->input('srvA_Id'); if ( !ServiceA::get( $srvA_id ) ) { return [ 'id' => $id, 'srvA_Id' => $srvA_id, 'status' => 'Error - srvA not found' ]; } return [ 'id' => $id, 'status' => 'Update ok' ]; } } } ?> Файл routes/api.php Код (Text): <?php use Illuminate\Http\Request; use App\Providers\MainProvider as MainProvider; Route::get('srvA', function () { $response = MainProvider\ServiceA::index(); return response( $response ,200); }); Route::get('srvA/{id}', function ( $id ) { $response = MainProvider\ServiceA::get( $id ); return response( $response ,200); }); Route::get('srvB', function () { $response = MainProvider\ServiceB::index(); return response( $response ,200); }); Route::get('srvB/{id}', function ( $id ) { $response = MainProvider\ServiceB::get( $id ); return response( $response ,200); }); Route::post('srvB', function ( Request $request ) { $response = MainProvider\ServiceB::post( $request ); return response( $response ,200); });
Думаю это будет тебе полезно: https://laraveldaily.com/how-to-structure-routes-in-large-laravel-projects/