Skip to content

Request Lifecycle

Flow Diagram

graph TB
    subgraph Octane["Laravel Octane v2 (Swoole/RoadRunner)"]
        A["HTTP Request"] --> B["Per-request resets\nDisconnectFromDatabases\nFlushTemporaryContainerInstances\nCollectGarbage"]
    end

    B --> C["Global Middleware\nTrustProxies, HandleCors\nPreventRequestsDuringMaintenance"]
    C --> D["CustomSession MW\nhighest priority (prepended)\nnamesapces cookie by surface"]

    D --> E{Route surface}

    E -->|"web routes"| F["user group\nEncryptCookies, AddQueuedCookies\nStartSession, ShareErrorsFromSession\nVerifyCsrfToken, SubstituteBindings\nEnsureGuestUser, HandleInertiaRequests\nAddLinkHeadersForPreloadedAssets"]

    E -->|"admin routes"| G["web group\nEncryptCookies, AddQueuedCookies\nStartSession, HandleInertiaRequests\nSubstituteBindings"]

    E -->|"api routes"| H["api group\nThrottleRequests, SubstituteBindings"]

    E -->|"webhook routes"| I["api group\nno CSRF\nno session"]

    F --> J["Route middleware\nauth/guest/verified\naddress_required\nproduct.is_private\nno-cache"]

    J --> K["Controller (thin)\ndelegates immediately"]
    K -->|"write"| L["Action class\nsingle-responsibility CQRS\nspatie/laravel-data DTO input"]
    K -->|"query"| M["Manager class\nstateful coordinator\nQueryBuilder (9 modules)"]

    L --> N["Eloquent Model\nMySQL / Redis"]
    M --> N

    N --> O{Response type}
    O -->|"web (first visit)"| P["Inertia::render()\nVue3 page component\nfull HTML response"]
    O -->|"web (XHR)"| Q["Inertia JSON response\npartial reload"]
    O -->|"admin"| R["Blade view\n+ Inertia on admin pages"]
    O -->|"api"| S["JSON response\nEloquent Resource"]

Purpose

Documents how a request travels from TCP socket to response under Octane's persistent-process model, including the complete middleware pipeline, delegation pattern, and Octane-specific risks.

Bootstrap Phase

Octane boots the Laravel application once per worker process, not per request. Per-request lifecycle:

  1. Worker receives HTTP request
  2. Octane fires per-request resets:
  3. DisconnectFromDatabases — closes DB connections (prevents stale PDO state)
  4. FlushTemporaryContainerInstances — removes scoped bindings
  5. CollectGarbage — runs GC cycle
  6. Kernel handles request through middleware pipeline
  7. Response returned; worker ready for next request

No full bootstrap per request — static properties, singleton state, and Config::set() mutations persist across requests within the same worker.

Middleware Pipeline

Priority Override (Kernel)

CustomSession is prepended to $middlewarePriority — runs before all other middleware, including session middleware.

Global Middleware

All requests: - TrustProxies - HandleCors - PreventRequestsDuringMaintenance - ValidatePostSize - TrimStrings - ConvertEmptyStringsToNull

Route Groups (RouteServiceProvider)

Group Routes Key Middleware
user routes/web/* custom-session:user, EnsureGuestUser, HandleInertiaRequests, VerifyCsrfToken
web (admin) routes/admin/* custom-session:admin, HandleInertiaRequests, VerifyCsrfToken
api routes/api.php, routes/webhook.php ThrottleRequests, no CSRF, no session

Named Route Middleware Aliases

Alias Class
auth Authenticate
auth:admin Authenticate (guard override)
guest RedirectIfAuthenticated
verified EnsureEmailIsVerified (custom)
address_required AddressRequired
custom-session:user CustomSession
custom-session:admin CustomSession
product.is_private EnsureProductIsPrivate
no-cache Cache-Control headers

CustomSession Detail

  • Detects route path prefix to determine surface (web vs admin)
  • Sets config('session.cookie') to {name}_user or {name}_admin
  • Sets session lifetime (default for user, 480 min for admin)
  • Config::set() mutation on a singleton — Octane risk: config mutation persists to next request in same worker if middleware fails to run

Controller → Action/Manager Pattern

All controllers are thin — they validate input (Form Request) and delegate:

  • Actions (app/Modules/*/Actions/): single-responsibility CQRS-style units. Accept DTOs (spatie/laravel-data). Stateless, safe to use as singletons.
  • Managers (app/Modules/*/Manager.php): stateful coordinators for multi-step operations (e.g., OrderManager::storeOrder(), LotteryManager).

Custom QueryBuilders (9 modules)

Module QueryBuilder
Product app/Modules/Product/QueryBuilders/
ProductVariation app/Modules/Product/QueryBuilders/
Order app/Modules/Order/QueryBuilders/
OrderDetail app/Modules/Order/QueryBuilders/
Lottery app/Modules/Lottery/QueryBuilders/
Membership (User) app/Modules/Membership/QueryBuilders/
Cart app/Modules/Cart/QueryBuilders/
CkcCode app/Modules/Chekicha/QueryBuilders/
Sales app/Modules/Sales/QueryBuilders/

Response Rendering

  • Web (first visit): Inertia::render('PageComponent', $props) → full HTML + embedded JSON
  • Web (XHR/navigation): Inertia JSON response → Vue3 partial swap
  • Admin pages: Inertia + Blade mix (admin uses Blade layout wrapping Inertia components)
  • API: JsonResource / array response
  • View::composer: injects cart item count into all web views (one extra query per web request)

Octane-Specific Considerations

  • Config::set() mutation risk: CustomSession mutates config('session.cookie') — if a request panics after config mutation but before session is set, next request inherits wrong cookie name.
  • Static Action classes: safe — no instance state.
  • Manager singletons: verify managers are not bound as singletons in module providers; user-specific state would leak between requests.
  • View::composer cart count query: fires on every web request for authenticated users.
  • Worker crash recovery: Octane restarts crashed workers automatically; crashed worker state is discarded.

Failure Paths

Failure Behaviour
VerifyCsrfToken mismatch 419 → errors.419.blade.php
Authenticate rejects Admin → admin.login, Order routes → login with return_to, all others → login
EnsureEmailIsVerified Redirect to email verification notice
AddressRequired Redirect to address form
Unhandled exception Handler.php branches: admin → Inertia error page; web → Blade error views; API → JSON
Octane worker crash Worker restarted; in-flight request dropped