
Building a Serverless League of Legends Stats Tracker: My AWS Rift Rewind Journey
I transformed a basic portfolio website into a full-stack serverless application that fetches real-time League of Legends player statistics through AWS Lambda and the Riot Games API, featuring a custom gaming-themed UI with animated elements. The project demonstrates practical problem-solving across CORS debugging, API deprecation handling, comprehensive error messaging, and data enrichment while staying entirely within AWS Free Tier limits.
What I Built
I transformed a personal portfolio site into a full-stack serverless application that integrates with the Riot Games API to fetch real-time League of Legends player statistics. The site features a gaming-themed UI with CSS animations and displays live data including summoner levels, champion mastery, and player rankings.
Architecture Overview
Frontend: AWS Amplify hosting with custom HTML/CSS/JavaScript and gaming-themed design with seven CSS animations
Backend: AWS Lambda (Python 3.13) with Lambda Function URLs, AWS Systems Manager Parameter Store for secure API key storage
External APIs: Riot Games Account-V1, Summoner-V4, and Champion Mastery-V4 APIs, plus Data Dragon CDN for champion images and metadata
Key Customizations
Starting from a basic portfolio template, I added:
- Custom Gaming Theme: Dark mode design with neon green accents, glowing text effects, and animated backgrounds
- Seven CSS Animations: Pulsing backgrounds, button ripple effects, staggered card animations, and progress bar shimmers
- Interactive Validation: Real-time error handling with specific, actionable user feedback
- Dynamic Data Display: Champion cards with images, mastery levels, and animated progress bars
- Two-Step API Integration: Converts modern Riot IDs to legacy summoner data seamlessly
Key Challenges & Solutions
- Challenge: CORS Configuration Conflicts
The Problem: Immediate 502 Bad Gateway errors when calling Lambda from the frontend. The browser console showed
'Access-Control-Allow-Origin' does not match '*, *' - the duplicate asterisk revealed headers were being set in two places.Solution: I had CORS configured both in Lambda Function URL console settings AND in my Lambda response headers. The fix was simple: remove ALL CORS headers from Lambda code and let Function URL settings handle it entirely.
Key Learning: Choose ONE place for CORS configuration. Lambda Function URLs make this easy through built-in console settings. The duplicate header was the debugging clue I needed.
- Challenge: Deprecated API Endpoint
The Problem: Getting 403 Forbidden errors from Riot API despite valid credentials. The old
/summoner/v4/summoners/by-name/{summonerName} endpoint was deprecated.Solution: Implemented a two-step process:
- Use Account-V1 API to convert Riot ID (GameName#Tagline) to PUUID
- Use Summoner-V4 API with PUUID to get player data
This also required understanding Riot's dual-routing system - Account API uses regional routing (americas, europe, asia) while Summoner/Mastery APIs use platform routing (na1, euw1, kr). I chose to handle this mapping client-side in JavaScript before calling Lambda, keeping the business logic close to the UI and reducing Lambda execution time:
1
2
3
4
5
6
const regionMap = {
'na1': 'americas',
'euw1': 'europe',
'kr': 'asia',
// ...
};Key Learning: API documentation matters. Always check for deprecation notices before debugging credential issues. Modern APIs favor universal identifiers over display names.
- Challenge: User-Friendly Error Messages
The Problem: Generic error messages weren't helping users understand what went wrong.
Solution: Implemented specific error handling for each scenario:
- 400: Invalid Riot ID format with example
- 403: API key expired notification
- 404: Summoner not found with helpful message
- 429: Rate limit exceeded
- 500: Server errors
Before:
{'error': 'Failed to fetch data'}After:
{'error': 'Riot ID not found', 'message': 'No account found for {name}#{tag}. Please check your Riot ID and try again.'}Key Learning: Good error messages turn frustration into understanding. Always include actionable guidance that helps users fix the problem themselves.
- Challenge: Data Enrichment for Better UX
The Problem: Champion IDs (67, 119, 236) meant nothing to users.
Solution: Integrated Riot's Data Dragon API to fetch champion metadata - names (Vayne, Draven, Lucian), titles ("the Night Hunter"), and images. This free CDN requires no authentication and provides all static game data.
Key Learning: Transform technical data into meaningful information. The Data Dragon CDN is perfect for static content - use it liberally to enhance user experience without authentication overhead.
Screenshots
Lambda Error Handling (See Git repo for complete Lambda)

CloudWatch Logs Validating Lambda Output

Search Interface

Search Results

Tips for Future Builders
1. Test CORS in Incognito Mode - Browser caching can make CORS issues persist even after fixes. Always test in private mode or hard refresh.
2. Use CloudWatch Logs Liberally - Add print statements at every major step. The small performance cost is worth the debugging visibility when things break.
3. Read API Documentation Thoroughly - Riot's docs clearly explained the Riot ID migration, but I initially skimmed them. Save hours by reading carefully first.
4. Validate Lambda Permissions Early - Missing IAM permissions can cause cryptic timeout errors. Check permissions before diving into code debugging.
5. Consider Rate Limits - Development API keys have strict limits (20 requests/second). For production, apply for a production key through the Riot Developer Portal.
6. Mobile-First Responsive Design - Test CSS on mobile devices early. Use CSS Grid with
auto-fit for responsive layouts that adapt automatically.Cost Analysis
Running this project in AWS Free Tier costs $0/month:
- Amplify: Free for 1 app with 15GB storage
- Lambda: Free for 1M requests, 400,000 GB-seconds compute
- CloudWatch Logs: 5GB ingestion, 5GB storage free
- Parameter Store: Free for standard parameters
Expected usage (~3,000 searches/month at 3 seconds each) stays well within free tier limits.
Conclusion
This challenge transformed a basic portfolio into a full-stack serverless application demonstrating practical AWS skills: hosting, serverless compute, secure credential management, and external API integration.
The gaming theme proved that technical projects can be visually engaging. The animations showcase front-end skills while the Lambda architecture demonstrates back-end competency. Most importantly, this project solves a real problem for League of Legends players.
Key Takeaway: Start simple, but don't be afraid to push boundaries. The AWS Free Tier is generous enough to support complex applications if you architect efficiently.
Live Project: https://main.d34u5e3l1s0uex.amplifyapp.com/
GitHub Repository: https://github.com/mflittle/rift-rewind-ml/
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article