Coder Social home page Coder Social logo

footballql's Introduction

FootballQL

GraphQL Java Spring Apache Maven Docker

This is a GraphQL API, made with Java 21 and Spring Boot 3, that has as its goal sync data from football-data.org and expose required data.

Table of Contents

Explaining The Architecture

This project was made using a Hexagonal type architecture. What this means is that the project is separated by modules and each module deals with a different concern that's unique to them, as well as their access level.

When it comes to dependencies and plugins, the Hexagonal architecture is extremely useful, given that you can inject dependencies, plugins and other needed tools only in the modules that actually need them.

  • The Application layer concerns everything that is going to be consumed (and visible) to the user - from controllers and models to error messages and docs (as well as configurations needed);
  • The Core layer concerns business rules, validations and exceptions, being the connection between the user interactions and the data to be consumed;
  • The Datasource layer concerns quite literally, the data that will be consumed - be it from a database or any external connection (in this particular case, the football-data.org imports).

Visual representation of the Hexagonal Architecture

Visual representation of the Hexagonal Architecture

How To Run The Project

This is a Java 21 and Spring Boot 3 based project, that uses Maven as it's build automation tool, and has a dockerized container to run the database,

That being said, in order to successfully run this application you'll need:

  • Java 21
  • Maven
  • Docker

Deploy Docker Database Container

All you need to do to have the container successfully deployed is enter the following commands on a terminal of your choice:

cd docker
docker-compose up -d

Maven & Java

If you have a IDE with a configured Java/Maven workspace, all you need to do is make sure your Run/Debug configuration classpath is pointing to the Application module.

Run/Debug Configuration on Intellij IDEA In this example, I'm using the Intellij IDEA IDE.

If you don't have an IDE configured, you can use the following commands in your terminal:

mvn clean
mvn install
cd application/
mvn spring-boot:run

note: Make sure you navigate to the application module before running spring boot.

Test The Application

If you followed the steps above correctly, you'll be able to access the GraphQL playground locally through http://localhost:8080/v1/playground ๐ŸŽ‰

Explaining The Mutations and Queries

Mutations


importLeague

Receives: leagueCode String as argument.
note: you can use the availableLeaguesForSync query to see a list of available League codes that can be used

Sample request

mutation ImportLeague {
  importLeague(leagueCode: "WC") {
    id
    code
    name
  }
}

Returns: Competition object with the complete tree of content that has been imported to the database.

Sample response

{
  "data": {
    "importLeague": {
      "code": "WC",
      "id": "2000",
      "name": "FIFA World Cup"
    }
  }
}

Queries


availableLeaguesForSync

Sample request

query AvailableLeagues {
    availableLeaguesForSync {
        code
        name
    }
}

Returns a list of available Leagues that can be imported using the importLeague Mutation

Sample response

{
  "data": {
    "availableLeaguesForSync": [
      {
        "code": "WC",
        "name": "FIFA World Cup"
      },
      {
        "code": "CL",
        "name": "UEFA Champions League"
      }
    ]
  }
}

findPlayers

Receives: leagueCode String as argument and teamName (optional).
note: The league provided has to be already synced, otherwise it will not return the expected result. Sample request

query FindPlayers {
    findPlayers(leagueCode: "CL", teamName: "Arsenal") {
        id
        person {
            dateOfBirth
            gamePosition
            id
            name
            nationality
        }
    }
}

Returns: A List of players.

Sample response

{
  "data": {
    "findPlayers": [
      {
        "id": "4832",
        "person": {
          "dateOfBirth": "1995-09-15",
          "gamePosition": "Goalkeeper",
          "id": "4707",
          "name": "David Raya",
          "nationality": "Spain"
        }
      },
      {
        "id": "5530",
        "person": {
          "dateOfBirth": "1998-05-14",
          "gamePosition": "Goalkeeper",
          "id": "4890",
          "name": "Aaron Ramsdale",
          "nationality": "England"
        }
      }
      // so it goes...
    ]
  }
}

findTeam

Receives: teamName String as argument and sortPlayers (optional)

Sample request

query FindTeamInformation {
    findTeam(teamName: "Brazil", sortPlayers: true) {
        id
        name
        shortName
        tla
        address
        area {
            code
            flag
            id
            name
        }
        coach {
            id
            person {
                name
                dateOfBirth
                nationality
            }
        }
        players {
            id
            person {
                name
                nationality
                dateOfBirth
                gamePosition
            }
        }
    }
}

Returns: A Team object with a list of players, sorted or unsorted depending on the sortPlayers argument.

Sample response

{
  "data": {
    "findTeam": {
      "id": "764",
      "name": "Brazil",
      "shortName": "Brazil",
      "tla": "BRA",
      "address": "Rua Victor Civita 66 Bloco 1, Edifico 5 Rio de Janeiro, RJ 22775-044",
      "area": {
        "code": "BRA",
        "flag": "https://crests.football-data.org/764.svg",
        "id": "2032",
        "name": "Brazil"
      },
      "coach": {
        "id": "11165",
        "person": {
          "name": "Fernando Diniz",
          "dateOfBirth": "1974-03-27",
          "nationality": "Brazil"
        }
      },
      "players": [
        {
          "id": "2028",
          "person": {
            "name": "Alex Sandro",
            "nationality": "Brazil",
            "dateOfBirth": "1991-01-26",
            "gamePosition": "Defence"
          }
        },
        {
          "id": "15904",
          "person": {
            "name": "Alex Telles",
            "nationality": "Brazil",
            "dateOfBirth": "1992-12-15",
            "gamePosition": "Defence"
          }
        },
        {
          "id": "1795",
          "person": {
            "name": "Alisson",
            "nationality": "Brazil",
            "dateOfBirth": "1992-10-02",
            "gamePosition": "Goalkeeper"
          }
        },
        {
          "id": "97085",
          "person": {
            "name": "Antony",
            "nationality": "Brazil",
            "dateOfBirth": "2000-02-24",
            "gamePosition": "Offence"
          }
        }
        // so it goes...
      ]
    }
  }
}

searchPlayer

An alternative way of searching for a player, using instead the name of the player as Argument, and returning a list of players as the result.

This can be used as an auto-complete, given a like sql query was used.

Receives: playerName String as Argument.

Sample request

query SearchPlayer {
    searchPlayer(playerName: "An") {
        id
        person {
            name
            dateOfBirth
            gamePosition
            nationality
        }
    }
}

Returns: A list of players (same as in findPlayers)


searchTeam

An alternative way of searching for a team, using instead the name of the team as Argument, and returning a list of team as the result.

This can be used as an auto-complete, given a like sql query was used.

Receives: teamName String as Argument.

Sample request

query SearchTeam {
    searchTeam(teamName: "Ar") {
        id
        name
        shortName
        tla
        address
    }
}

Returns: A list of teams (same object as in findTeam - but listed)


Conclusion And Final Considerations

I sure hope you can see that I'm very passionate about the work I do and I hope it shows in my code ๐Ÿ˜Š

This project was started on 2023-12-15, and given it's short time I wasn't able to finish the unit tests, other than that, I'm very proud of it ๐Ÿ˜

If you have any questions, feel free to reach out on any of my socials:

Larissa Silva | LinkedIn nickeldumbb | Twitter larssslv | Instagram larssslv | twitch


This and other Projects are available on my github page!

GitHub

footballql's People

Contributors

laasilva avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.