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 DevRecallTest yourself — Laravel quizMore 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