Skip to content

GraphQL

Matthew Olsson edited this page May 4, 2020 · 3 revisions

Introduction: What is GraphQL?

GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools. - GraphQL

In short, GraphQL provides an alternate way to design APIs. It differs from REST in that all the data you are requesting is sent in one request, and all of the data requested is given to you as a response. Additionally, GraphQL is strongly typed, which means you know exactly what kind of data you are going to receive.

If this sounds interesting and you'd like to know more, check out the official GraphQL website. This wiki page details how to use the SlothPixel GraphQL api endpoint.

SlothPixel's GraphQL Endpoint

SlothPixel exposes a GraphQL endpoint at /api/graphql. This is the only endpoint that support GraphQL.

In large, the GraphQL API mirrors the structure of the REST API. Let's look at two requests for getting a player's Arcade coins

REST request:

https://api.slothpixel.me/api/players?playerName=<playerName>

GraphQL request:

{
  players {
    player(player_name: "<playerName>") {
      stats {
        Arcade {
          coins
        }
      }
    }
  }
}

There are a couple differences to discuss here. First and foremost, you'll notice we didn't actually specify anything about Arcade coins in the REST request -- because that's not how REST requests work. When we send that request, we'll get a very large response from the server. This is quite wasteful, since we only want a single number. In contract, sending the GraphQL request above produces an output similar to:

{
  "data": {
    "players": {
      "player": {
        "stats": {
          "Arcade": {
            "coins": 461848
          }
        }
      }
    }
  }
}

There is no waste here -- we get only the data we asked for. This is the benefit of using GraphQL.

Using the Endpoint

To experiment with the GraphQL endpoint, it is highly recommended to use an application like Insomnia that can easily craft a GraphQL request and view the response. We recommend Insomnia in particular because it has strong support for GraphQL. When writing your request, Insomnia will fetch the GraphQL spec from SlothPixel and give you auto-completion as you type.

If you want to use it in an application, download the library for your language of choice. GraphQL is language agnostic, and any language you decide to use will have a supported GraphQL library available through the language or the community.

GraphQL vs. REST

There are some differences between the SlothPixel REST API and the GraphQL API. The best way to view the exact differences between the two is to look directly at the GraphQL spec, located here. The Query type at the top of the spec is the entry point into the rest of the spec -- you'll want to start there. Note that the JSON return type means that the endpoint is untyped, and you will get untyped-data. Send a request first to see what you get!

For convenience, the Query type is summarized here:

{
  bans: { ... }
  boosters: { ... }
  get_leaderboard_template(template: String): [JSON]
  guild(player_name: String, populate_players: String) { ... }
  leaderboards(<see spec for parameters>) [JSON]
  
  players: {
    player(player_name: String) { ... }
    achievements(player_name: String) { ... }
    quests(player_name: String) { ... }
    recent_games(player_name: String) { ... }
  }

  skyblock: {
    all_auctions(<see spec for parameters>): { ... }
    auctions(item_id: String, from: Float, to: Float) { ... }
    items: JSON
    profiles(player_name: String): JSON
    profile(player_name: String, profile_id: String): JSON
    bazaar(item_id: String) { ... }
  }
  
  metadata: JSON
}

Examples

Some examples are provided here as a basic template for your requests

Arcade coins for multiple players (using Fragments!)

Request

{
  players {
    Ecolsson: player(player_name: "Ecolsson") {
      ...ArcadeCoins
    }
    builder_247: player(player_name: "builder_247") {
      ...ArcadeCoins
    }
  }
  
}

fragment ArcadeCoins on Player {
  stats {
    Arcade {
      coins
    }
  }
}

Response

{
  "data": {
    "players": {
      "Ecolsson": {
        "stats": {
          "Arcade": {
            "coins": 461848
          }
        }
      },
      "builder_247": {
        "stats": {
          "Arcade": {
            "coins": 28880565
          }
        }
      }
    }
  }
}

Getting a player's guild information

Request

{
  guild(player_name: "builder_247") {
    created
    description
    exp
    level
    name
  }
}

Response

{
  "data": {
    "guild": {
      "created": 1451743004798,
      "description": "An all games guild, with a special love of paintball",
      "exp": 220382593,
      "level": 80.79,
      "name": "Chimera"
    }
  }
}

TODO: More examples