Skip to main content
The ChampionController handles HTTP requests for champion browsing and detail pages.

Overview

Located at source/app/Http/Controllers/ChampionController.php, this controller:
  • Displays paginated champion lists with role information
  • Shows individual champion details with relationships
  • Implements aggressive caching for performance
  • Uses route model binding for clean URLs

Class Definition

namespace App\Http\Controllers;

use App\Models\Champion;
use App\Models\ChampionRoles;
use Illuminate\Support\Facades\Cache;

class ChampionController extends Controller
{
    // Controller methods
}

Routes

Defined in source/routes/web.php:44-45:
Route::get('champions', static fn () => (new ChampionController)->index())
    ->name('champions.index');
    
Route::get('champion/{champion}', static fn (Champion $champion) => (new ChampionController)->show($champion))
    ->name('champions.show');

Methods

index()

Displays a listing of all champions.
public function index()
{
    $eightHoursInSeconds = 60 * 60 * 8;

    $champions = Cache::remember('championsListAllCache', $eightHoursInSeconds, 
        static fn() => Champion::orderBy('name')->get()
    );

    $roles = Cache::remember('championsRolesCache', $eightHoursInSeconds, 
        static fn() => ChampionRoles::orderBy('champion_name')->get()
    );

    return view('champions.index', ['champions' => $champions, 'roles' => $roles]);
}

Return Value

view
Illuminate\View\View
Rendered champions.index Blade template

View Data

champions
Collection<Champion>
All champions ordered alphabetically by name
roles
Collection<ChampionRoles>
Champion role/lane assignments ordered by champion name

Cache Strategy

Results are cached for 8 hours using two separate cache keys:
  • championsListAllCache - Champion collection
  • championsRolesCache - Role assignments

Query Performance

Champion::orderBy('name')->get()
  • No eager loading on index page (to minimize payload size)
  • Alphabetical sorting by champion name
  • Returns all champions in a single query

Usage Example

Access the champion list at:
GET /champions

show()

Displays a specific champion’s detail page.
public function show(Champion $champion)
{
    $threeDaysInSeconds = 60 * 60 * 24 * 3;

    $champion = Cache::remember('championShowCache' . $champion->slug, $threeDaysInSeconds, 
        static fn() => $champion->load('streamers', 'skins', 'lanes')
    );

    $streamers = $champion->streamers;

    return view('champions.show', ['champion' => $champion, 'streamers' => $streamers]);
}

Parameters

champion
Champion
required
Champion model instance (automatically resolved via route model binding)

Return Value

view
Illuminate\View\View
Rendered champions.show Blade template

View Data

champion
Champion
Champion model with eager-loaded relationships:
  • streamers - Associated Twitch streamers
  • skins - All skins for this champion
  • lanes - Recommended lanes/roles
streamers
Collection<Streamer>
Collection of streamers who play this champion (extracted for convenience)

Cache Strategy

Each champion page is cached for 3 days (72 hours) with a unique cache key based on the champion’s slug.
Cache key format: championShowCache{slug} Examples:
  • championShowCacheahri
  • championShowCaseyasuo
  • championShowCaselee-sin

Route Model Binding

Laravel automatically resolves the {champion} route parameter:
// URL: /champion/ahri
// Laravel finds: Champion::where('slug', 'ahri')->firstOrFail()
If a champion with the given slug doesn’t exist, Laravel returns a 404 Not Found error automatically.

Usage Example

Access a champion detail page:
GET /champion/ahri
GET /champion/lee-sin
GET /champion/master-yi

Eager Loading Strategy

Index Page (No Eager Loading)

The index page doesn’t eager load relationships to keep the payload small:
Champion::orderBy('name')->get()
Reason: The index page only displays champion names and icons, not related data.

Show Page (Aggressive Eager Loading)

The detail page loads all necessary relationships upfront:
$champion->load('streamers', 'skins', 'lanes')
Loaded Relationships:
Type: HasManyTwitch streamers associated with this champion
public function streamers(): HasMany
{
    return $this->hasMany(Streamer::class, 'champion_name', 'name');
}
Type: HasManyAll skins available for this champion
public function skins(): HasMany
{
    return $this->hasMany(ChampionSkin::class, 'champion_id', 'champion_id');
}
Type: HasManyRecommended lanes and roles for this champion
public function lanes(): HasMany
{
    return $this->hasMany(ChampionRoles::class, 'champion_name', 'name');
}

Cache Invalidation

The controller doesn’t automatically invalidate cache when champion data changes. Manual cache clearing may be needed after data updates:
// Clear champion list cache
Cache::forget('championsListAllCache');
Cache::forget('championsRolesCache');

// Clear specific champion detail cache
Cache::forget('championShowCache' . $champion->slug);

// Or clear all champion caches
Cache::flush();
Consider implementing cache tags or event listeners to automatically invalidate caches when champion data is updated.

Performance Considerations

8-Hour Index Cache

Champion list rarely changes, so 8-hour cache is appropriate

3-Day Detail Cache

Individual champions change even less frequently

Eager Loading

Prevents N+1 queries on detail pages

Route Model Binding

Automatic model resolution keeps controllers clean

Champion Model

View the Champion model API reference

Champion Feature

Learn about the champion browsing feature

Architecture

Understand the MVC architecture

Data Sources

Learn where champion data comes from

Build docs developers (and LLMs) love