All topics
Backend · Learning hub

Laravel notes for developers

Master Laravel with a curated set of 2 developer notes — core concepts, patterns, and interview prep. Maintained by the DevRecall team.

Save this stack to your DevRecallMore Backend notes
Laravel

Laravel Interview Questions

Laravel Interview Questions What is the service container? IoC (Inversion of Control) container that manages class dependencies. Resolves type-hinted dependenci

Laravel Interview Questions

  • What is the service container? IoC (Inversion of Control) container that manages class dependencies. Resolves type-hinted dependencies automatically via reflection. Register bindings in service providers

  • What are service providers? Bootstrapping classes where you register bindings, event listeners, middleware, routes. All loaded in config/app.php providers array. boot() runs after all providers registered

  • How does route model binding work? Laravel resolves {user} to User::findOrFail($id) automatically when the method type-hints the model. Custom: use resolveRouteBinding() on the model or explicit binding in RouteServiceProvider

  • What is N+1 problem and how to fix? Loading each relationship in a loop fires a query per record. Fix: eager load with with('posts') or withCount('posts'). Detect with Laravel Debugbar or Telescope

  • Jobs vs Events vs Listeners? Job: queued unit of work (send email, process image). Event: signals something happened. Listener: reacts to event (can be queued). Use events for decoupled side effects; jobs for async processing

  • What is Sanctum vs Passport? Sanctum: lightweight auth for SPA/mobile (cookie-based sessions + API tokens). Passport: full OAuth2 server. Use Sanctum for first-party clients; Passport for third-party OAuth

  • How to optimise Laravel performance? Route/config/view caching (php artisan optimize), eager loading, Redis for cache/sessions/queues, queue long operations, Octane for persistent worker (Swoole/RoadRunner)

Laravel

Laravel Essentials

Laravel Essentials Routing & Controllers // routes/api.php use App\Http\Controllers\UserController; Route::get('/users', [UserController::class, 'index']); Rout

Laravel Essentials

Routing & Controllers

// routes/api.php
use App\Http\Controllers\UserController;

Route::get('/users', [UserController::class, 'index']);
Route::post('/users', [UserController::class, 'store']);
Route::get('/users/{user}', [UserController::class, 'show']);
Route::put('/users/{user}', [UserController::class, 'update']);
Route::delete('/users/{user}', [UserController::class, 'destroy']);

// Resource routes (all 7 actions at once)
Route::apiResource('users', UserController::class);

// Route groups with middleware
Route::middleware(['auth:sanctum'])->group(function () {
    Route::apiResource('posts', PostController::class);
    Route::get('/profile', [ProfileController::class, 'show']);
});

// app/Http/Controllers/UserController.php
class UserController extends Controller
{
    public function index(Request $request): JsonResponse
    {
        $users = User::when($request->search, fn($q, $s) =>
            $q->where('name', 'like', "%{$s}%")
        )->paginate(20);

        return response()->json($users);
    }

    public function store(StoreUserRequest $request): JsonResponse
    {
        $user = User::create($request->validated());
        return response()->json($user, 201);
    }

    public function show(User $user): JsonResponse  // route model binding
    {
        return response()->json($user->load('posts'));
    }

    public function update(UpdateUserRequest $request, User $user): JsonResponse
    {
        $user->update($request->validated());
        return response()->json($user);
    }

    public function destroy(User $user): Response
    {
        $user->delete();
        return response()->noContent();
    }
}

Eloquent ORM

// Model definition
class User extends Model
{
    protected $fillable = ['name', 'email', 'password'];
    protected $hidden = ['password', 'remember_token'];
    protected $casts = [
        'email_verified_at' => 'datetime',
        'settings' => 'array',
        'is_active' => 'boolean',
    ];

    // Relationships
    public function posts(): HasMany { return $this->hasMany(Post::class); }
    public function profile(): HasOne { return $this->hasOne(Profile::class); }
    public function roles(): BelongsToMany { return $this->belongsToMany(Role::class); }

    // Accessors / mutators (Laravel 9+)
    protected function password(): Attribute
    {
        return Attribute::set(fn($v) => bcrypt($v));
    }

    // Scopes
    public function scopeActive($query) { return $query->where('is_active', true); }
    public function scopeSearch($query, $term) {
        return $query->where('name', 'like', "%{$term}%");
    }
}

// Querying
User::all();
User::find(1);
User::findOrFail(1);
User::where('email', 'a@b.com')->first();
User::active()->search('alice')->paginate(20);
User::with('posts.comments')->get();          // eager loading
User::withCount('posts')->orderBy('posts_count')->get();

// Create / update / delete
User::create(['name' => 'Alice', 'email' => 'a@a.com']);
User::updateOrCreate(['email' => 'a@a.com'], ['name' => 'Alice']);
$user->update(['name' => 'Bob']);
$user->delete();
User::where('is_active', false)->delete();    // bulk delete

Migrations & Validation

// Migrations
Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->foreignId('user_id')->constrained()->cascadeOnDelete();
    $table->string('title');
    $table->string('slug')->unique();
    $table->longText('body');
    $table->enum('status', ['draft', 'published'])->default('draft');
    $table->timestamp('published_at')->nullable();
    $table->timestamps();
    $table->softDeletes();
    $table->index(['user_id', 'status']);
});

// php artisan make:migration create_posts_table
// php artisan migrate
// php artisan migrate:rollback
// php artisan migrate:fresh --seed

// Form Request validation
class StoreUserRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'name'     => ['required', 'string', 'max:255'],
            'email'    => ['required', 'email', 'unique:users,email'],
            'password' => ['required', 'min:8', 'confirmed'],
            'role'     => ['required', Rule::in(['admin', 'user'])],
        ];
    }
    public function authorize(): bool { return true; }
}

// Artisan commands
// php artisan make:model Post -mcr   // model + migration + controller + resource
// php artisan make:request StorePostRequest
// php artisan route:list
// php artisan tinker

Keep your Laravel knowledge sharp.

Save this stack to your personal DevRecall — add your own notes, track what you're learning, and share what you know with the community.

Get started — free forever