2 min read

Building a Small Laravel Contact Flow

A code-heavy walkthrough of a Laravel contact endpoint with validation, rate limiting, persistence, notifications, and Pest coverage.

JO Jerry Ogunniyi
Building a Small Laravel Contact Flow

This sample post exists to stress-test the article view with real code blocks, headings, links, and paragraphs. It walks through a small Laravel contact flow from route to test.

The route

The route keeps the public surface easy to scan and makes the rate limiter visible.

<?php

use App\Http\Controllers\ContactMessageController;
use Illuminate\Support\Facades\Route;

Route::post("/contact", [ContactMessageController::class, "store"])
    ->middleware("throttle:contact")
    ->name("contact.store");

The request object

Validation lives in a form request so the controller only receives trusted input.

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreContactMessageRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            "name" => ["required", "string", "max:120"],
            "email" => ["required", "email", "max:160"],
            "message" => ["required", "string", "min:20"],
        ];
    }
}

The controller

The controller creates the message and sends the notification. The interesting behavior stays explicit.

<?php

namespace App\Http\Controllers;

use App\Http\Requests\StoreContactMessageRequest;
use App\Models\ContactMessage;
use App\Notifications\ContactMessageReceived;
use Illuminate\Support\Facades\Notification;

class ContactMessageController
{
    public function store(StoreContactMessageRequest $request)
    {
        $message = ContactMessage::create($request->validated());

        Notification::route("mail", config("mail.from.address"))
            ->notify(new ContactMessageReceived($message));

        return back()->with("status", "Message sent.");
    }
}

The test

The feature test protects the behaviour users care about: a valid message is stored, and a notification is sent.

<?php

use App\Models\ContactMessage;
use App\Notifications\ContactMessageReceived;
use Illuminate\Support\Facades\Notification;

use function Pest\Laravel\assertDatabaseHas;
use function Pest\Laravel\post;

it("stores contact messages", function (): void {
    Notification::fake();

    post(route("contact.store"), [
        "name" => "Ada Lovelace",
        "email" => "ada@example.com",
        "message" => "Could you review the integration boundaries for this API?",
    ])->assertRedirect()->assertSessionHas("status");

    assertDatabaseHas(ContactMessage::class, [
        "email" => "ada@example.com",
    ]);

    Notification::assertSentOnDemand(ContactMessageReceived::class);
});

That gives the post template a realistic mix of paragraph rhythm, headings, inline links, and long code samples.

Share this post

$
navigate open

Privacy Preferences

This site uses essential cookies and local preferences to keep things working smoothly, including theme and consent choices.