DEV Community

Cover image for Developing an API to Retrieve Football Game Schedules - Using Docker and AWS Services
Anthony Uketui
Anthony Uketui

Posted on

Developing an API to Retrieve Football Game Schedules - Using Docker and AWS Services

Who Doesn't Love Football? ⚽

Before diving into my passion for the game, let’s tackle an important question:

Why Do We Need an API for Football Schedules?

Manually gathering football schedules from multiple websites is time-consuming and inefficient. Instead, an API allows us to integrate live updates directly into applications, websites, or analytics tools, making it easy to access real-time football schedules seamlessly.

🛠 Breaking It Down with an Analogy

Imagine you want to order food from a restaurant. Instead of going to the kitchen, checking ingredients, and preparing the meal yourself, you simply ask the waiter for what you want. The waiter communicates with the kitchen, retrieves the meal, and serves it to you—quick, accurate, and hassle-free.

An API works like that waiter. When you need football game schedules, instead of manually collecting data from multiple sources, the API acts as a middleman, fetching the latest updates for you instantly.

✅ This saves time, ensures accuracy, and eliminates manual work, making it easier for apps and websites to display real-time football schedules.


Project Overview

In this project, I developed an API that retrieves football game schedules using:

  • Flask (for the API)
  • Docker (for containerization)
  • AWS Services (for scalability and reliability)

Tech Stack Breakdown

🚀 Flask Framework

Flask is a lightweight Python web framework that allows for rapid development. I used it to create API endpoints that handle requests for football game schedules.

📦 Docker

Docker enables packaging applications into containers—ensuring that they run consistently across different environments. By containerizing the Flask app, I simplified deployment and eliminated compatibility issues.

☁️ AWS Services Used

  • Elastic Container Registry (ECR) – A managed container registry to store our Docker images securely.
  • Elastic Container Service (ECS) – Used to deploy and manage the Dockerized API efficiently.
  • Elastic Load Balancing (ELB) – Distributes traffic across multiple instances to ensure high availability.
  • API Gateway – Exposes the API via a secure and scalable endpoint.

This combination ensures the API can handle real-time requests with high availability.


Development and Deployment Steps

1️⃣ Developing the Flask API

  • Created a Python-based Flask application to handle API requests.
  • Ensured the application fetched and processed football schedules from Football-Data.org.

2️⃣ Containerizing the Application with Docker

  • Wrote a Dockerfile to define the environment and dependencies.
  • Built and tested a Docker image locally.

3️⃣ Pushing the Docker Image to AWS ECR

  • Created an ECR repository to store the Docker image.
  • Tagged and pushed the image to ECR.

4️⃣ Deploying on AWS ECS

  • Set up an ECS cluster to manage containerized applications.
  • Defined a task definition specifying the Docker image and resource requirements.
  • Created a service to maintain the desired number of running tasks.

5️⃣ Configuring Networking & Load Balancing

  • Implemented an Application Load Balancer (ALB) for traffic distribution.
  • Configured security groups to allow API access.

6️⃣ Exposing the API via AWS API Gateway

  • Created an API Gateway to serve as the entry point.

- Routed traffic through API Gateway to the ALB.

Developing the API with Python (Flask)

I used Python to create the API, ensuring it could efficiently fetch and format football schedules.

Key Features

✅ Fetches live football schedules

✅ Formats responses in JSON

✅ Handles errors gracefully

Flask Code:

from flask import Flask, jsonify
import requests
import os

app = Flask(__name__)

FOOTBALL_API_URL = "https://api.football-data.org/v4/matches"
FOOTBALL_API_KEY = os.getenv("FOOTBALL_API_KEY", "your_api_key_here")

@app.route('/football', methods=['GET'])
def get_football_schedule():
    """Fetches upcoming football matches and returns as JSON."""
 8   try:
        headers = {"X-Auth-Token": FOOTBALL_API_KEY}
        response = requests.get(FOOTBALL_API_URL, headers=headers)
        response.raise_for_status()
        data = response.json()

        matches = data.get("matches", [])
        if not matches:
            return jsonify({"message": "No upcoming football matches found.", "matches": []}), 200

        formatted_matches = [
            {
                "competition": match.get("competition", {}).get("name", "Unknown"),
                "home_team": match.get("homeTeam", {}).get("name", "Unknown"),
                "away_team": match.get("awayTeam", {}).get("name", "Unknown"),
                "venue": match.get("venue", "Unknown"),
                "date": match.get("utcDate", "Unknown"),
            }
            for match in matches
        ]

        return jsonify({"message": "Football schedule fetched successfully.", "matches": formatted_matches}), 200

    except Exception as e:
        return jsonify({"message": "An error occurred.", "error": str(e)}), 500

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)

Enter fullscreen mode Exit fullscreen mode

To confirm the code works we test it in our local machine by running the command below.

Image description

Here's the output. It works!

Image description

Why Did I Containerize the Application? 🍽

A Simple Analogy

Using Docker is like a chef preparing a meal in a food container instead of serving it on a plate.

Without a container, the food might spill, mix with other meals, or not fit different kitchens. But with a container, the meal stays intact, portable, and works anywhere—whether in a restaurant, a food truck, or a customer's home.

Similarly, Docker packages our app with everything it needs, ensuring it runs smoothly on any system without issues.


What Does a Dockerfile Do? 📜

A Dockerfile is like a recipe—it provides step-by-step instructions to build our container consistently.

Here’s my Dockerfile:

# Use a lightweight Python image  
FROM python:3.9-slim  

# Set the working directory inside the container  
WORKDIR /app  

# Copy the requirements file into the container  
COPY requirements.txt requirements.txt  

# Install dependencies  
RUN pip install -r requirements.txt  

# Copy all files from the current directory into the container  
COPY . .  

# Expose the port  
EXPOSE 8080  

# Command to run the application  
8CMD ["python", "app.py"]
Enter fullscreen mode Exit fullscreen mode

Deploying on AWS ☁️

Since we're deploying on AWS, I used ECR instead of Docker Hub for:

Better security

Faster performance

Seamless AWS integration

Pushing the Docker Image to AWS ECR

Step 1: Create an ECR Repository

If you haven't already created an ECR repository, do so with:

Image description

Step 2: Authenticate Docker with AWS ECR

Before pushing the image, log in to AWS ECR using the AWS CLI:

Image description

Step 3: Tag the Docker Image

Retrieve the repository URL and tag your Docker image:

Image description

Step 4: Push the Image to ECR

Now, push the tagged image to the repository:

Image description

Configuring AWS ECS

Why Do We Need to Configure ECS?

Think of ECS as a restaurant kitchen that runs and manages containers. But before it can start serving meals (running containers), you need to:

Set up the kitchen (configure ECS)

Tell the chefs what recipes to use (define services and tasks)

Assign kitchen equipment (8choose EC2 or Fargate)

Without proper ECS configuration, it won’t know where or how to run our containers.

Steps to Configure ECS

1️⃣ Create a Cluster – The foundation for running containers.

Image description

2️⃣ Define a Task Definition – Like a recipe that specifies:

  • Which container image to use (the image in our ECR)
  • CPU & memory allocation
  • Port settings and environment variables

Image description

3️⃣ Create a service:

  • We set up how many tasks we want defined(we used 2)
  • We set up security groups, Iam Policies(default)
  • We configured our load balancer from here.

Image description

Image description


Load Balancing

To distribute incoming traffic evenly across multiple containers, we configured an Application Load Balancer (ALB).

Image description

Image description

High availability – If one container goes down, traffic is redirected to another.

Better performance – Ensures no single container is overloaded.

To verify, we searched for our load balancer under EC2 Services and accessed our API via the ALB's DNS. It worked! 🎉

Image description


Creating an API Gateway Endpoint

Instead of exposing our ECS services directly, we used API Gateway as a front door to handle incoming requests.

Analogy: API Gateway is Like a Receptionist

Just like a receptionist in a big company handles all incoming guests, directs them appropriately, and ensures security, API Gateway:

📌 Receives incoming requests

📌 Routes them to the right backend service (ECS)

📌 Ensures security and authentication

Steps to Set Up API Gateway

1️⃣ Created a REST API

Image description

Image description

2️⃣ Created a resource & method

Image description

Image description

Image description

Image description

3️⃣ Deployed the API

Image description

Now, we can invoke our API successfully to access football game schedules. 🚀

Image description


Conclusion

Through this process, we successfully:

✅ Built and containerized a football schedule API

✅ Deployed it on AWS using ECS & Fargate

✅ Configured a load balancer for high availability

✅ Integrated API Gateway for security and request management

Now, users can access football schedules via our API! ⚽

Top comments (1)

Collapse
 
patrick_ibe profile image
patrick ibe

Great content boss