Api's - Kitch41/Blok-Tech GitHub Wiki

My API

For my API's i need 2 different API's:

  • 1 WebAPI
  • 1 regular api

After failing this project i came back to this project with a fresh look and now i see there are a few api's i can use. I did some research into Regular api's and which one i wanted to use. i ended up looking into Game API's. I want to show a few games on the page. For the webapi i decided to go with the intersection observer since it works well with the game api i chose.

Research

I started looking for Api's on the publicapi's github. There i found a few api's but none that i needed. I started looking on the internet where i found the steamapi. This can list a lot of games a user owns. But after trying to get it to work it wouldn't give me an api key. After that i started looking for more api's until i ended at the igdb api. Its an api that can lookup a lot of information on games.

Out of the few possible api's the IGDB api is the best. The Steam list api needs a key and i wasn't able to get that. The igdb api does come with a few quirks. But i managed to get through them by using postman to test the calls. after a while the api gave me 10 items with the highest rating

How it works

IGDB API

Show Code
async function fetchGames(apiKey, clientId, offset, limit) {
  const gamesResponse = await fetch('https://api.igdb.com/v4/games', {
    method: 'POST',
    headers: {
      'Client-ID': clientId,
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'text/plain'
    },
    body: `fields name,rating,cover,summary; sort rating desc; limit ${limit}; offset ${offset};`
  });
  const games = await gamesResponse.json();

  const coverIds = games.map(game => game.cover).filter(id => id != null);

  const coversResponse = await fetch('https://api.igdb.com/v4/covers', {
    method: 'POST',
    headers: {
      'Client-ID': clientId,
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'text/plain'
    },
    body: `fields url; where id = (${coverIds.join(',')});`
  });
  const covers = await coversResponse.json();

  const coverMap = covers.reduce((acc, cover) => {
    acc[cover.id] = cover.url;
    return acc;
  }, {});

  return games.map(game => {
    if (game.cover) {
      game.coverUrl = coverMap[game.cover];
    }
    return game;
  });
}

The IGDB API works a little complicated. You have to first get an auth key by calling this api:

POST: https://id.twitch.tv/oauth2/token?client_id=abcdefg12345&client_secret=hijklmn67890&grant_type=client_credentials

Then you can use that token to call the database and request things in the header. Like title, description and other things. The thing that makes this database a little hard is the fact you have to call a different api to get the cover images of each item. so i had to get a little creative with this.

For this code i had to use chatgpt to connect the game to the cover since i'm not good enough yet to use map and reduce this efficiently.

Intersection Observer

Show Code
    gamesButton.addEventListener('click', function () {
        toggleTrigger(create);
        document.body.classList.add('long');
        gamesButton.classList.add('active');
        overviewButton.classList.remove('active');
        gamesContainer.classList.remove('hidden');
        overviewContainer.classList.add('hidden');
        observe();
    });

    function toggleTrigger(state) {
        const loadMoreTrigger = document.getElementById('loadMoreTrigger');
        if (state === create && !loadMoreTrigger) {
            const newLoadMoreTrigger = document.createElement('div');
            newLoadMoreTrigger.id = 'loadMoreTrigger';
            const gamesContainer = document.getElementById('gamesContainer');
            gamesContainer.insertAdjacentElement('afterend', newLoadMoreTrigger);
        } else if (state === remove && loadMoreTrigger) {
            loadMoreTrigger.remove();
        }
    }


    function observe() {
        // intersection observer
        const observer = new IntersectionObserver(entries => {
            if (entries[0].isIntersecting) {
                loadMoreGames();
            }
        }, {
            root: null,
            rootMargin: '0px',
            threshold: 1.0
        });

        // intersection observer observes if div is in view
        observer.observe(document.querySelector('#loadMoreTrigger'));
    }

    async function loadMoreGames() {
        try {
            const response = await fetch(`/more-games?offset=${offset}&limit=10`);
            const newGames = await response.json();
            newGames.forEach(game => {
                const truncatedSummary = game.summary.length > 200 ? game.summary.substring(0, 200) + '...' : game.summary;
                const gameElement = document.createElement('div');
                gameElement.classList.add('game');
                gameElement.innerHTML = `
              <img src="${game.coverUrl}" alt="${game.name} Cover" />
              <div class="game-details">
                <h2>${game.name}</h2>
                <p>Rating: ${game.rating}</p>
                <p>${truncatedSummary}</p>
              </div>
            `;
                gamesContainer.appendChild(gameElement);
            });
            offset += 10; // Update the offset for the next batch of games
        } catch (error) {
            console.error('Error loading more games:', error);
        }
    }

});

The intersection observer that i used is very simple to understand. It makes you able to perfom an Javascript action whenever a certain element comes into view on your webpage. I used this to load new games when the last few games were on the screen. This way i created a doomscrolling app with games.

At first i struggled a bit with the API since the items wouldn't load fast enough. I fixed this by moving the element up a bit and making the initial load of the amount of games a bit longer.

Other Api's

I looked into some other potential api's but decided not to use them afterwards. here are some:

  • Fortnite API, Fortnite Stats Database ( requires API Key )
  • FREETOPLAY, Free-To-Play Games Database ( harder to use )
  • Steam, Steam games database ( harder to use and requires API Key )

Steam API

The one API that i got close to using was the steam Web API. It is a set of tools that lets developers interact with steam. It can access game details, user info, achievements, leaderboards and ofcourse library's which is really useful for making apps that show a users game library.

When I first tried using the Steam API for my project, I got an error right away. It was super frustrating and I couldn’t figure out what was wrong. Since I was on a deadline, I decided to drop it and look for other solutions. Thats when i found my current API and this one was a lot easier to use.

Looking back now, I see that the Steam API works fine. The initial error was just an error that went away with time it seems. If i were to choose between the 2 API's i think i would've chosen the steam API since it is somewhat more extensive eventhough it is harder to use.

Conclusion

I decided to go with the IGDB API. It is an extensive api with covers as well as many other game details. I chose this above the others is because it is easier to use and has more relevant data.

⚠️ **GitHub.com Fallback** ⚠️