Если вы какое-то время создавали приложения на Django и решили изучить Laravel, поначалу вам может показаться, что вы заново учитесь бэкенд-разработке.

Это не так.

Синтаксис другой. Структура проекта другая. Терминология другая. Но многие архитектурные идеи, лежащие в основе Laravel, покажутся вам удивительно знакомыми, если вы работали с Django.

Эта статья — практическое руководство для  разработчиков на Django, переходящих на Laravel. Вместо того чтобы изучать концепции Laravel изолированно, мы сопоставим их с аналогами из Django и построим ментальную модель того, как работает приложение на Laravel.

В конце вы сможете посмотреть на проект на Laravel и понять, где должны находиться маршруты, контроллеры, модели, валидация, аутентификация, бизнес-логика и операции с базой данных.


1. Django против Laravel: Ментальный перевод

Самый простой способ начать изучение Laravel для разработчика на Django — составить таблицу ментального соответствия.

Django Laravel
Django project Laravel application
Django app No exact equivalent
 urls.py   routes/web.php ,  routes/api.php 
View function / Class-Based View Controller method
Django ORM Eloquent ORM
Model Model
 models.py   app/Models/ 
DRF Serializer API Resource / Form Request
Django Forms Form Requests
Middleware Middleware
 settings.py   .env  +  config/ 
 manage.py   artisan 
Django migrations Laravel migrations
Django templates Blade
 JsonResponse  / DRF Response  response()->json() 
Django signals Events / Observers
Management commands Artisan commands
 pip  Composer
 requirements.txt   composer.json 
Celery Laravel Queues / Jobs

Главное — не предполагать, что это точные замены один в один.

Это не так.

Это просто полезные ментальные мостики.

Например, Laravel API Resource и сериализатор из Django REST Framework помогают формировать ответы API, но работают они по-разному.


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

Представьте, что фронтенд на React отправляет:

 POST /api/properties
 

Упрощенный жизненный цикл запроса в Laravel выглядит следующим образом:

 React / Browser / Mobile App
            |
            v
       HTTP Request
            |
            v
      public/index.php
            |
            v
        Bootstrap
            |
            v
        Middleware
            |
            v
          Router
            |
            v
        Controller
            |
       +----+----+
       |         |
       v         v
   Validation  Business Logic
                 |
                 v
              Model
                 |
                 v
             Database
                 |
                 v
              Resource
                 |
                 v
           JSON Response
                 |
                 v
               Client
 

Эту архитектуру следует держать в голове при изучении Laravel.


Свежий проект на Laravel выглядит примерно так:

 my-project/
│
├── app/
│   ├── Console/
│   ├── Exceptions/
│   ├── Http/
│   │   ├── Controllers/
│   │   ├── Middleware/
│   │   └── Requests/
│   │
│   ├── Models/
│   └── Providers/
│
├── bootstrap/
│
├── config/
│
├── database/
│   ├── factories/
│   ├── migrations/
│   └── seeders/
│
├── public/
│   └── index.php
│
├── resources/
│   ├── views/
│   ├── css/
│   └── js/
│
├── routes/
│   ├── web.php
│   ├── api.php
│   └── console.php
│
├── storage/
│
├── tests/
│
├── vendor/
│
├── .env
├── artisan
└── composer.json
 

Если вы пришли из мира Django, поначалу эта структура может показаться непривычной.

Django поощряет разделение функционала на приложения:

 project/
├── users/
├── properties/
├── bookings/
└── payments/
 

Laravel не навязывает такой подход.

Вместо этого типичное приложение на Laravel организует код вокруг зон ответственности:

 app/
├── Models/
├── Http/
│   ├── Controllers/
│   ├── Requests/
│   └── Middleware/
└── Services/
 

Вы по-прежнему можете организовывать крупный проект на Laravel по доменам или фичам, но сам Laravel не заставляет вас создавать отдельное «приложение» для каждой возможности.


Если вы пользовались Django, маршрутизация покажется вам очень простой.

В Django вы можете написать:

 path(
    "properties/",
    views.properties
)
 

В Laravel используется:

 Route::get(
    '/properties',
    [PropertyController::class, 'index']
);
 

Маршруты в Laravel обычно размещаются в:

 routes/
├── web.php
├── api.php
└── console.php
 

Например:

 Route::get('/properties', [
    PropertyController::class,
    'index'
]);
 

POST:

 Route::post('/properties', [
    PropertyController::class,
    'store'
]);
 

PUT:

 Route::put('/properties/{id}', [
    PropertyController::class,
    'update'
]);
 

DELETE:

 Route::delete('/properties/{id}', [
    PropertyController::class,
    'destroy'
]);
 

Laravel делает HTTP-метод явным прямо в определении маршрута.


В Django вы можете написать:

 path(
    "properties/<int:id>/",
    views.property_detail
)
 

В Laravel:

 Route::get(
    '/properties/{id}',
    [PropertyController::class, 'show']
);
 

Затем ваш контроллер может принять ID:

 public function show($id)
{
    //
}
 

Запрос вида:

 GET /properties/10
 

передает:

 $id = 10;
 

Laravel также поддерживает более мощную функцию под названием  связывание моделей с маршрутами (route model binding), к которой мы вернемся позже.


Эту концепцию перенести проще всего.

Функция-представление в Django может выглядеть так:

 def properties(request):
    properties = Property.objects.all()

    return JsonResponse({
        "properties": list(
            properties.values()
        )
    })
 

Контроллер в Laravel может выглядеть так:

 class PropertyController extends Controller
{
    public function index()
    {
        $properties = Property::all();

        return response()->json([
            'properties' => $properties
        ]);
    }
}
 

Концептуально:

 Django View
     ≈
Laravel Controller Method
 

Создайте контроллер с помощью Artisan:

 php artisan make:controller PropertyController
 

Laravel создаст:

 app/Http/Controllers/PropertyController.php
 

Если есть одна функция Laravel, которую разработчики на Django поймут практически сразу, то это  Eloquent.

Eloquent — это ORM в Laravel.

Django:

 Property.objects.all()
 

Laravel:

 Property::all();
 

Django:

 Property.objects.get(id=1)
 

Laravel:

 Property::find(1);
 

Django:

 Property.objects.filter(
    status="available"
)
 

Laravel:

 Property::where(
    'status',
    'available'
)->get();
 

Django:

 Property.objects.filter(
    price__gt=10000
)
 

Laravel:

 Property::where(
    'price',
    '>',
    10000
)->get();
 

Синтаксис отличается, но основополагающая идея та же:

 Application
     |
     v
ORM
     |
     v
Database
 

Создайте модель в Laravel:

 php artisan make:model Property
 

Вы получите что-то вроде:

 app/Models/Property.php
 

Модель может выглядеть следующим образом:

 class Property extends Model
{
    protected $fillable = [
        'name',
        'location',
        'price',
    ];
}
 

Затем вы можете создавать записи:

 $property = Property::create([
    'name' => 'Apartment A',
    'location' => 'Nairobi',
    'price' => 25000,
]);
 

Эквивалент в Django:

 Property.objects.create(
    name="Apartment A",
    location="Nairobi",
    price=25000
)
 

Одна из концепций Laravel, которая поначалу может запутать разработчиков на Django, — это  массовое заполнение (mass assignment).

Вы часто будете видеть:

 protected $fillable = [
    'name',
    'location',
    'price',
];
 

Это определяет, какие атрибуты могут быть назначены через такие методы, как:

 Property::create([
    'name' => 'Apartment A',
    'location' => 'Nairobi',
    'price' => 25000,
]);
 

Это важный механизм безопасности.

Вам следует разобраться с  $fillable  и  $guarded  на раннем этапе изучения Eloquent.


Если вы работали с миграциями в Django, миграции в Laravel покажутся вам знакомыми.

Django:

 python manage.py makemigrations
python manage.py migrate
 

Laravel:

 php artisan make:migration create_properties_table
 

Затем:

 php artisan migrate
 

Миграция может выглядеть следующим образом:

 Schema::create('properties', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('location');
    $table->decimal('price', 10, 2);
    $table->timestamps();
});
 

Сравните это с Django:

 class Property(models.Model):
    name = models.CharField(max_length=255)
    location = models.CharField(max_length=255)
    price = models.DecimalField(
        max_digits=10,
        decimal_places=2
    )
 

Синтаксис отличается, но вы описываете ту же структуру базы данных.


Если в Django используется:

 python manage.py
 

То в Laravel:

 php artisan
 

Artisan — один из важнейших инструментов в экосистеме Laravel.

Некоторые команды, которые вы будете использовать чаще всего:

 php artisan serve
 

Запуск сервера разработки.

 php artisan route:list
 

Вывод списка маршрутов вашего приложения.

 php artisan make:model Property
 

Создание модели.

 php artisan make:controller PropertyController
 

Создание контроллера.

 php artisan make:request StorePropertyRequest
 

Создание запроса валидации.

 php artisan make:resource PropertyResource
 

Создание API Resource.

 php artisan migrate
 

Запуск миграций.

 php artisan migrate:rollback
 

Откат миграций.

 php artisan migrate:fresh
 

Удаление всех таблиц и пересоздание базы данных.

 php artisan db:seed
 

Запуск сидеров.

 php artisan optimize:clear
 

Очистка кэша конфигураций, маршрутов, представлений и других оптимизированных файлов Laravel.

Хорошее правило:

Если вы сомневаетесь, есть ли в Laravel встроенная команда CLI для какой-то задачи, сначала проверьте Artisan.


Связи в Eloquent от Laravel — это еще одна область, в которой разработчики на Django почувствуют себя как дома.

Предположим, объект недвижимости принадлежит арендодателю.

Django:

 class Property(models.Model):
    landlord = models.ForeignKey(
        User,
        on_delete=models.CASCADE
    )
 

Laravel:

 class Property extends Model
{
    public function landlord()
    {
        return $this->belongsTo(
            User::class
        );
    }
}
 

Теперь вы можете обратиться к:

 $property->landlord;
 

Предположим, арендодателю принадлежит несколько объектов недвижимости.

Laravel:

 class Landlord extends Model
{
    public function properties()
    {
        return $this->hasMany(
            Property::class
        );
    }
}
 

Затем:

 $landlord->properties;
 

В Django это выглядело бы так:

 landlord.properties.all()
 

при условии, что вы настроили соответствующий  related_name .


Django:

 class Student(models.Model):
    courses = models.ManyToManyField(
        Course
    )
 

Laravel:

 public function courses()
{
    return $this->belongsToMany(
        Course::class
    );
}
 

Затем:

 $student->courses;
 

И снова терминология меняется, но связи в базе данных остаются прежними.


Одна из важнейших концепций ORM — избежание лишних запросов к базе данных.

Laravel:

 Property::with('landlord')->get();
 

Примерный аналог в Django:

 Property.objects.select_related(
    "landlord"
)
 

Для связей с коллекциями:

 Property::with('bookings')->get();
 

концептуально схоже с:

 Property.objects.prefetch_related(
    "bookings"
)
 

Это важно, поскольку и приложения на Django, и приложения на Laravel могут страдать от печально известной  проблемы N+1 запросов.


Именно здесь архитектура начинает заметно различаться.

В Django REST Framework вы можете разместить валидацию внутри сериализатора:

 class PropertySerializer(
    serializers.ModelSerializer
):
    class Meta:
        model = Property
        fields = "__all__"

    def validate_price(self, value):
        if value < 0:
            raise serializers.ValidationError(
                "Price cannot be negative"
            )

        return value
 

В Laravel валидация запросов обычно выносится в отдельный класс  Form Request.

Создайте его:

 php artisan make:request StorePropertyRequest
 

Затем:

 class StorePropertyRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'name' => [
                'required',
                'string',
                'max:255'
            ],

            'location' => [
                'required',
                'string'
            ],

            'price' => [
                'required',
                'numeric',
                'min:0'
            ],
        ];
    }
}
 

После этого внедрите его в ваш контроллер:

 public function store(
    StorePropertyRequest $request
) {
    //
}
 

Laravel автоматически выполнит валидацию входящего запроса до того, как выполнится метод вашего контроллера.


В Laravel есть  API Resources для преобразования моделей в ответы API.

Создайте один из них:

 php artisan make:resource PropertyResource
 

Затем:

 class PropertyResource extends JsonResource
{
    public function toArray(
        Request $request
    ): array {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'location' => $this->location,
            'price' => $this->price,
        ];
    }
}
 

Затем:

 return new PropertyResource($property);
 

Для коллекций:

 return PropertyResource::collection(
    Property::all()
);
 

Полезная ментальная модель:

 DRF Serializer
       |
       +---- validation/input
       |
       +---- representation/output

Laravel
       |
       +---- Form Request
       |       -> validation
       |
       +---- API Resource
               -> representation
 

В Laravel эти зоны ответственности разделены более явно.


Разработчикам на Django концепция middleware уже знакома.

Django:

 MIDDLEWARE = [
    ...
]
 

Laravel:

 Route::middleware('auth')->group(
    function () {
        // protected routes
    }
);
 

Вы можете создать middleware с помощью Artisan:

 php artisan make:middleware CheckUserRole
 

Например:

 if ($request->user()->role !== 'admin') {
    abort(403);
}
 

Middleware полезно для задач, которые должны выполняться до или после выполнения контроллера, например:

  • Аутентификация
  • Логирование
  • Ограничение частоты запросов (rate limiting)
  • CORS
  • Проверка ролей
  • Модификация запроса

Laravel поддерживает несколько подходов к аутентификации.

Одно из часто встречающихся решений для API и SPA-приложений —  Laravel Sanctum.

Типичная архитектура может выглядеть так:

 React
  |
  v
Laravel API
  |
  v
Authentication
  |
  v
Controller
 

Если вы пришли из мира Django REST Framework и JWT, не думайте, что Sanctum — это просто «JWT для Laravel».

Sanctum предоставляет возможности аутентификации по API-токену и для SPA, но его модель и рабочий процесс отличаются от аутентификации на основе JWT.

Также Laravel предоставляет:

  • Гейты (Gates)
  • Политики (Policies)
  • Middleware
  • Драйверы аутентификации (guards)

Все это становится особенно важным по мере роста вашего приложения.


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

Вы можете проверить это прямо внутри контроллера, но в Laravel предусмотрены специальные механизмы авторизации, такие как  Политики (Policies).

Концептуально:

 User
  |
  v
Can this user update this property?
  |
  +---- YES ---> Continue
  |
  +---- NO ----> 403 Forbidden
 

Это позволяет держать логику авторизации отдельно от бизнес-логики.

Если вы использовали разрешения в Django, этот раздел потребует вашего внимательного изучения.


Для конфигурации окружения Laravel использует файл  .env .

Например:

 APP_NAME=Laravel
APP_ENV=local
APP_DEBUG=true

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=my_database
DB_USERNAME=root
DB_PASSWORD=
 

Разработчикам на Django этот подход может быть знаком по таким пакетам, как  python-decouple  или  django-environ .

Конфигурация Laravel хранится здесь:

 config/
 

Например:

 config/
├── app.php
├── database.php
├── auth.php
├── cache.php
└── filesystems.php
 

Разработчики на Django могут воспринимать это как более децентрализованный аналог файла  settings.py .


Серверный движок шаблонов в Laravel называется  Blade.

Django:

 <h1>{{ property.name }}</h1>
 

Blade:

 <h1>{{ $property->name }}</h1>
 

Django:

 {% for property in properties %}
    {{ property.name }}
{% endfor %}
 

Blade:

 @foreach($properties as $property)
    {{ $property->name }}
@endforeach
 

Если вы создаете Laravel API, которое потребляется React-приложением, шаблонизатор Blade вам почти не понадобится.

Если же вы создаете традиционное веб-приложение на Laravel, роль Blade возрастает многократно.


Это одна из тех концепций Laravel, на понимание которой я рекомендую разработчикам на Django потратить чуть больше времени.

Предположим, ваш контроллер зависит от определенного сервиса:

 class PropertyController extends Controller
{
    public function __construct(
        PropertyService $propertyService
    ) {
        $this->propertyService =
            $propertyService;
    }
}
 

 Сервис-контейнер (Service Container) Laravel может автоматически разрешить эту зависимость за вас.

Концептуально:

 Controller
    |
    | requires
    v
PropertyService
    |
    v
Laravel Service Container
 

Это встроенная в Laravel система внедрения зависимостей (dependency injection).

Как только вы разберетесь с сервис-контейнером, такие концепции, как сервис-провайдеры, привязки (bindings), интерфейсы и внедрение зависимостей, станут гораздо понятнее.


Для реализации сложной бизнес-логики в приложениях на Laravel часто создают отдельные классы сервисов.

Например:

 app/
└── Services/
    ├── PropertyService.php
    ├── BookingService.php
    └── PaymentService.php
 

Внутри сервиса может находиться следующий код:

 class PropertyService
{
    public function create(
        array $data
    ) {
        return Property::create($data);
    }
}
 

Тогда ваш контроллер примет следующий вид:

 public function store(
    StorePropertyRequest $request
) {
    $property =
        $this->propertyService->create(
            $request->validated()
        );

    return new PropertyResource(
        $property
    );
}
 

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

Вместо такого подхода:

 Controller
 ├── validation
 ├── authorization
 ├── payment
 ├── database logic
 ├── email
 ├── notifications
 └── business rules
 

вы можете использовать такую структуру:

 Controller
     |
     v
Service
     |
     +---- Model
     +---- Payment
     +---- Notification
     +---- Events
 

Однако не стоит создавать класс сервиса для каждого двухстрочного SQL-запроса.

Применяйте эту архитектуру тогда, когда она действительно улучшает разделение ответственности.


В Laravel доступна событийно-ориентированная архитектура (event-driven architecture) с помощью событий (Events) и слушателей (Listeners).

Представьте, что пользователь регистрируется:

 User registers
      |
      v
UserRegistered event
      |
      +----> SendWelcomeEmail
      |
      +----> CreateProfile
      |
      +----> NotifyAdmin
 

Это позволяет вынести второстепенные операции из основной логики обработки запроса.

Разработчикам на Django это может показаться в чем-то похожим на сигналы (signals), хотя события и слушатели в Laravel предлагают другую и зачастую более явную архитектуру.


Если вы использовали Celery в связке с Django, концепция джоб (Jobs) и очередей (Queues) в Laravel будет вам понятна.

Представьте, что отправка 10 000 писем может сильно замедлить обработку запроса.

Вместо этого:

 HTTP Request
     |
     v
Create Job
     |
     v
Queue
     |
     v
Worker
     |
     v
Send Emails
 

Создайте задачу (job):

 php artisan make:job SendNewsletter
 

А затем отправьте её в очередь:

 SendNewsletter::dispatch();
 

Пользователю больше не нужно ждать завершения тяжелой операции.

Этот подход крайне полезен для:

  • Отправки писем
  • Уведомлений
  • Обработки изображений
  • Генерации отчетов
  • Платежей
  • Импорта
  • Экспорта
  • Ресурсоемких вычислений

Кроме того, в Laravel встроена система планирования задач (task scheduling).

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

 Every day
    |
    v
Find overdue rent
    |
    v
Send reminders
 

Или такая:

 Every hour
    |
    v
Clean expired sessions
 

Этот функционал можно комбинировать с командами Artisan и очередями задач.

Если вы пришли из экосистемы Django, воспринимайте это как аналог инструментов, которые обычно реализуются через cron, Celery Beat, кастомные management-команды или схожие утилиты.


Laravel предоставляет средства для наполнения базы данных начальными данными (seeders):

 php artisan db:seed
 

Например:

 Property::create([
    'name' => 'Apartment A',
    'location' => 'Nairobi',
    'price' => 25000,
]);
 

Фабрики (Factories) позволяют генерировать тестовые данные для разработки.

Например:

 Property::factory()
    ->count(50)
    ->create();
 

Концептуально это очень похоже на использование таких инструментов, как  factory_boy  в проектах на Django.


Давайте соберем все компоненты воедино.

Предположим, мы создаем следующий эндпоинт:

 POST /api/properties
 

Маршрут (Route):

 Route::post(
    '/properties',
    [PropertyController::class, 'store']
);
 

Валидация запроса:

 class StorePropertyRequest
    extends FormRequest
{
    public function rules(): array
    {
        return [
            'name' => [
                'required',
                'string',
                'max:255'
            ],

            'location' => [
                'required',
                'string'
            ],

            'price' => [
                'required',
                'numeric',
                'min:0'
            ],
        ];
    }
}
 

Модель:

 class Property extends Model
{
    protected $fillable = [
        'name',
        'location',
        'price',
    ];
}
 

Контроллер:

 class PropertyController extends Controller
{
    public function store(
        StorePropertyRequest $request
    ) {
        $property = Property::create(
            $request->validated()
        );

        return new PropertyResource(
            $property
        );
    }
}
 

Ресурс:

 class PropertyResource extends JsonResource
{
    public function toArray(
        Request $request
    ): array {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'location' => $this->location,
            'price' => $this->price,
        ];
    }
}
 

Клиент отправляет:

 POST /api/properties
Content-Type: application/json
 
 {
    "name": "Apartment A",
    "location": "Nairobi",
    "price": 25000
}
 

Laravel обрабатывает запрос:

 POST /api/properties
        |
        v
Route
        |
        v
PropertyController
        |
        v
StorePropertyRequest
        |
        v
validated()
        |
        v
Property::create()
        |
        v
Eloquent
        |
        v
MySQL
        |
        v
PropertyResource
        |
        v
JSON Response
 

Такова архитектура реального API на Laravel.


Допустим, вы уже создали систему для аренды недвижимости на Django.

Ваша архитектура на Django может выглядеть так:

 Django
│
├── users
├── properties
├── bookings
├── payments
└── maintenance
 

Эквивалент в Laravel может выглядеть следующим образом:

 Laravel
│
├── Models
│   ├── User.php
│   ├── Property.php
│   ├── Booking.php
│   ├── RentPayment.php
│   └── MaintenanceTicket.php
│
├── Http
│   ├── Controllers
│   │   ├── AuthController.php
│   │   ├── PropertyController.php
│   │   ├── BookingController.php
│   │   └── PaymentController.php
│   │
│   ├── Requests
│   │   ├── LoginRequest.php
│   │   ├── StorePropertyRequest.php
│   │   └── StoreBookingRequest.php
│   │
│   └── Resources
│       ├── UserResource.php
│       ├── PropertyResource.php
│       └── BookingResource.php
│
└── Services
    ├── AuthService.php
    ├── PropertyService.php
    └── PaymentService.php
 

Тогда цикл обработки запроса в API превращается в:

 React
  |
  | POST /api/properties
  v
Laravel Router
  |
  v
PropertyController
  |
  v
StorePropertyRequest
  |
  v
Authorization
  |
  v
PropertyService
  |
  v
Property Model
  |
  v
MySQL
  |
  v
PropertyResource
  |
  v
JSON
  |
  v
React
 

Это очень полезная архитектура для тех, кто уже уверенно чувствует себя с Django REST Framework.


Одна из крупнейших ошибок при переходе на другой фреймворк — попытка перенести архитектуру привычного старого фреймворка в новый.

Не стоит считать, что:

 Laravel = Django written in PHP
 

Это не так.

Например, не нужно автоматически создавать:

 PropertySerializer
PropertyView
PropertyForm
PropertyService
 

просто потому, что в Django вы бы структурировали проект именно так.

Вместо этого разберитесь, что предлагает Laravel, и используйте каждый компонент там, где это уместно.

Аналогично, не пишите абсолютно всё внутри контроллеров только потому, что Laravel это позволяет.

Контроллер на 500 строк бизнес-логики — это плохая архитектура для Laravel.


Я рекомендую изучать Laravel примерно в следующем порядке.

Уровень 1 — Базовые знания

Изучите:

 PHP
  ↓
Composer
  ↓
Laravel installation
  ↓
Project structure
  ↓
Artisan
  ↓
Routes
  ↓
Controllers
 

Уровень 2 — Базы данных

Затем:

 Migrations
  ↓
Models
  ↓
Eloquent
  ↓
Relationships
  ↓
Query Builder
  ↓
Factories
  ↓
Seeders
 

Уровень 3 — Разработка API

Затем:

 HTTP Requests
  ↓
Validation
  ↓
Form Requests
  ↓
API Resources
  ↓
Pagination
  ↓
JSON responses
 

Уровень 4 — Безопасность

Затем:

 Authentication
  ↓
Middleware
  ↓
Policies
  ↓
Gates
  ↓
Authorization
  ↓
Sanctum
 

Уровень 5 — Архитектура Laravel

Затем:

 Service Container
  ↓
Dependency Injection
  ↓
Service Providers
  ↓
Services
  ↓
Events
  ↓
Listeners
  ↓
Jobs
  ↓
Queues
 

Уровень 6 — Продакшн

И наконец:

 Caching
  ↓
Queues
  ↓
Scheduling
  ↓
Logging
  ↓
Testing
  ↓
Workers
  ↓
Deployment
 

Если вы уже читали документацию Django, не пытайтесь освоить все возможности Laravel одновременно.

Сконцентрируйтесь на следующих аспектах:

1. Eloquent

Разберитесь с методами:

 Model::all();

Model::find();

Model::where();

Model::create();

Model::update();

Model::delete();
 

Затем переходите к связям (relationships) и жадной загрузке (eager loading).

2. Form Requests

Узнайте, как в Laravel валидируются входящие данные.

3. API Resources

Поймите, как в Laravel модели преобразуются в ответы API.

4. Middleware

Узнайте, где выполняются аутентификация, ограничение частоты запросов (rate limiting) и обработка входящих запросов.

5. Policies и Gates

Разберитесь с механизмом авторизации.

6. Сервис-контейнер (Service Container)

Это одна из важнейших архитектурных концепций Laravel.

7. Внедрение зависимостей (Dependency Injection)

Поймите, как Laravel разрешает зависимости.

8. Задачи и очереди (Jobs and Queues)

Это особенно важно, если вы создаете приложения для продакшна.

9. События и слушатели (Events and Listeners)

Научитесь отделять второстепенные операции от основного потока выполнения приложения.

10. Artisan

Вы будете пользоваться этой консольной утилитой постоянно.


Если вы переходите с Django, помните следующую схему:

                        LARAVEL

                         Request
                            |
                            v
                       Middleware
                            |
                            v
                          Route
                            |
                            v
                       Controller
                            |
                 +----------+----------+
                 |                     |
                 v                     v
          Form Request             Policy
          Validation            Authorization
                 |
                 v
               Service
                 |
                 v
              Eloquent
                 |
                 v
              Database
                 |
                 v
              Resource
                 |
                 v
            JSON Response
 

Совсем не обязательно задействовать каждый блок для каждого запроса.

Простой эндпоинт может выглядеть так:

 Request
   ↓
Route
   ↓
Controller
   ↓
Model
   ↓
Response
 

Более сложный эндпоинт может включать больше шагов:

 Request
   ↓
Middleware
   ↓
Route
   ↓
Form Request
   ↓
Policy
   ↓
Controller
   ↓
Service
   ↓
Eloquent
   ↓
Event
   ↓
Job
   ↓
Resource
   ↓
Response
 

Архитектура растет по мере усложнения самого приложения.


Переход с Django на Laravel не означает, что вам приходится учить всё с нуля.

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

Вы уже знаете, что такое:

  • HTTP
  • Маршрутизация (Routing)
  • REST API
  • Модели
  • ORM
  • Базы данных
  • Связи (Relationships)
  • Миграции
  • Аутентификация
  • Авторизация
  • Middleware
  • Валидация
  • Сериализация
  • Фоновые задачи

Laravel просто реализует многие из этих идей иначе.

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

Вместо того чтобы думать:

«Где в Laravel аналог моего файла из Django?»

начните задаваться вопросом:

«Какую задачу я решаю и какой компонент Laravel для этого предназначен?»

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

И раз вы уже создавали REST API на Django, вы не начинаете свой путь в Laravel с нуля.

Вы изучаете  новую экосистему, используя уже имеющиеся знания.

Быстрее всего освоиться поможет воссоздание проекта, структура которого вам уже знакома по Django.

Например:

 Landlord/Tenant API
       |
       +-- Authentication
       +-- Users
       +-- Properties
       +-- Bookings
       +-- Rent Payments
       +-- Maintenance Tickets
       +-- Roles
       +-- Authorization
       +-- Notifications
 

Создайте ту же систему на Laravel, осознанно сопоставляя понятия:

 Django              Laravel

urls.py          →  routes
views.py         →  controllers
models.py        →  Eloquent models
DRF serializers  →  requests/resources
ORM              →  Eloquent
middleware       →  middleware
manage.py        →  Artisan
Celery           →  Jobs/Queues
settings.py      →  config + .env
 

Именно тогда Laravel перестает казаться совершенно чуждым фреймворком и превращается в еще один инструмент для решения задач, которые вы уже умеете решать.