Documentation Index Fetch the complete documentation index at: https://mintlify.com/rico-vz/HeimerdingerLoL/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Heimdinger.lol aggregates League of Legends data from multiple sources to provide comprehensive champion, skin, and asset information. The application implements a robust fallback system to ensure data availability.
Data Source Priority
Boris API (Primary)
Custom internal API providing processed champion data
Meraki Analytics (Fallback)
Community-maintained CDN with structured LoL data
Community Dragon (Assets)
High-quality champion images and ability icons
Boris Static Data Client
The BorisStaticDataClient service is the primary interface for fetching champion and rate data with automatic fallback handling.
Service Location
app / Services / BorisStaticDataClient . php
Configuration
Boris API credentials are configured in config/services.php:
'boris' => [
'url' => env ( 'BORIS_URL' , 'https://boris.heimerdinger.lol' ),
'api_key' => env ( 'BORIS_API_KEY' ),
],
Set BORIS_URL and BORIS_API_KEY in your .env file to configure the connection.
Data Fetching Methods
Get Champions Data
Retrieves all champion information with automatic fallback:
app/Services/BorisStaticDataClient.php:21
public function getChampions () : array
{
$payload = $this -> fetchWithFallback (
self :: CHAMPIONS_ENDPOINT ,
self :: MERAKI_CHAMPIONS_URL ,
fn ( mixed $payload ) : bool => $this -> isChampionPayload ( $payload )
);
return $this -> normalizeChampionPayload ( $payload );
}
Endpoints:
Primary : https://boris.heimerdinger.lol/lolstaticdata/champions.json
Fallback : https://cdn.merakianalytics.com/riot/lol/resources/latest/en-US/champions.json
Get Champion Rates
Fetches win rates, pick rates, and ban rates:
app/Services/BorisStaticDataClient.php:32
public function getChampionRates () : array
{
return $this -> fetchWithFallback (
self :: CHAMPION_RATES_ENDPOINT ,
self :: MERAKI_CHAMPION_RATES_URL ,
fn ( mixed $payload ) : bool => $this -> isChampionRatesPayload ( $payload )
);
}
Endpoints:
Primary : https://boris.heimerdinger.lol/lolstaticdata/championrates.json
Fallback : https://cdn.merakianalytics.com/riot/lol/resources/latest/en-US/championrates.json
Fallback System
The service implements a sophisticated fallback mechanism to ensure data availability:
Attempt Boris API
Make request to Boris API with authentication: app/Services/BorisStaticDataClient.php:109
$response = Http :: withHeaders ([
'X-API-Key' => ( string ) config ( 'services.boris.api_key' ),
]) -> get ( $this -> borisUrl () . $endpoint );
Validate Payload
Verify the response matches expected data structure: app/Services/BorisStaticDataClient.php:141
private function isChampionPayload ( mixed $payload ) : bool
{
if ( ! is_array ( $payload ) || $payload === []) {
return false ;
}
$firstChampion = reset ( $payload );
return is_array ( $firstChampion ) && isset ( $firstChampion [ 'id' ]);
}
Fall Back to Meraki
If Boris fails or returns invalid data, fetch from Meraki: app/Services/BorisStaticDataClient.php:66
$payload = $this -> fetchFromMeraki ( $merakiUrl );
if ( $validator ( $payload )) {
Log :: warning ( 'Using Meraki static data fallback.' );
return $payload ;
}
Throw Exception
If both sources fail, throw a descriptive exception: app/Services/BorisStaticDataClient.php:88
throw new RuntimeException (
sprintf ( 'Unable to fetch static data from Boris or Meraki for [%s].' , $borisEndpoint )
);
Error Logging
All failures are logged with context for debugging:
app/Services/BorisStaticDataClient.php:52
Log :: warning ( 'Boris static data request failed.' , [
'source' => 'boris' ,
'endpoint' => $borisEndpoint ,
'status' => $exception -> getCode () ?: null ,
'message' => $exception -> getMessage (),
]);
Monitor your logs for frequent fallbacks to Meraki, which may indicate Boris API issues.
Community Dragon provides high-quality champion assets directly from game files.
Champion Images
Images are accessed via model accessors:
app/Models/Champion.php:108
public function getChampionSquareImageAttribute () : string
{
return 'https://raw.communitydragon.org/pbe/plugins/rcp-be-lol-game-data/global/default/v1/champion-icons/'
. $this -> champion_id . '.png' ;
}
Ability Icons
Each ability has a dedicated accessor:
Q Ability
W Ability
Passive
public function getChampionAbilityIconQAttribute () : string
{
return 'https://cdn.communitydragon.org/latest/champion/'
. $this -> champion_id . '/ability-icon/q' ;
}
Usage in Views
< img src = " {{ $champion -> champion_square_image }} " alt = " {{ $champion -> name }} " >
< img src = " {{ $champion -> champion_ability_icon_q }} " alt = "Q Ability" >
Data Normalization
The service normalizes data structures between sources:
app/Services/BorisStaticDataClient.php:176
private function normalizeChampionPayload ( array $payload ) : array
{
// Meraki returns keyed array, Boris returns list
if ( array_is_list ( $payload )) {
return $payload ;
}
return array_values ( $payload );
}
This ensures consistent data structure regardless of source.
Payload Validation
Champion Payload
Validates champion data structure:
app/Services/BorisStaticDataClient.php:141
private function isChampionPayload ( mixed $payload ) : bool
{
if ( ! is_array ( $payload ) || $payload === []) {
return false ;
}
if ( array_is_list ( $payload )) {
return isset ( $payload [ 0 ][ 'id' ]);
}
$firstChampion = reset ( $payload );
return is_array ( $firstChampion ) && isset ( $firstChampion [ 'id' ]);
}
Champion Rates Payload
Validates rate data structure:
app/Services/BorisStaticDataClient.php:156
private function isChampionRatesPayload ( mixed $payload ) : bool
{
return is_array ( $payload ) && isset ( $payload [ 'data' ]) && is_array ( $payload [ 'data' ]);
}
Environment Configuration
Required environment variables for data sources:
BORIS_URL = https://boris.heimerdinger.lol
BORIS_API_KEY = your-api-key-here
# Optional: Riot API for additional features
RGAPI_KEY = "RGAPI-00000000-0000-0000-0000-000000000000"
USER_AGENT = "Heimerdinger/1.0 (Heimerdinger.lol) PHP"
The Riot API key (RGAPI_KEY) is optional for core functionality but required for live sale rotation data.
Best Practices
Always cache API responses to reduce external requests: $champions = Cache :: remember ( 'champions_data' , 3600 , function () {
return app ( BorisStaticDataClient :: class ) -> getChampions ();
});
Wrap data fetching in try-catch blocks: try {
$champions = $client -> getChampions ();
} catch ( RuntimeException $e ) {
Log :: error ( 'Failed to fetch champions' , [ 'error' => $e -> getMessage ()]);
// Return cached data or show error message
}
Respect API rate limits by implementing appropriate caching and request throttling.
Testing Data Sources
Test the Boris client in Tinker:
$client = app ( \App\Services\ BorisStaticDataClient :: class );
$champions = $client -> getChampions ();
count ( $champions ); // Should return ~160+ champions
Next Steps
Architecture Understand the overall application architecture
Artisan Commands Learn about available CLI commands for data management