blog.natfan.io

Rants and ravings from a techy brit.
(Now hosted on DigitalOcean!)
Dark Mode?

Hypixel

First posted 1 year ago.
Last updated 1 year ago.

This is a work in progress post.

So, you're probably here because you want to know how natfan.io/hypixel[1] works. Well then, buckle up because this is going to be a bumpy ride! Okay, maybe not, but it's a tale into my journey to RESTful JSON APIs and one of the reasons I love them so much.

Step I: Getting Access

Honestly, this bit was easy. Hypixel allow you to log into their servers and type /api to get a new API key.

Getting your API key.[2]
(This key is invalid.)

Copy down what they give you and keep it safe, you only get to see the key once, and we will be using it a lot later.

Step II: Making our First Call

Now that we have our API, let's take a look at the endpoints that we can use. The endpoints are listed here[3], but the one we're going to be focusing on today is player.md[4], which is located at https://api.hypixel.net/player[5].

If you were to go to that link directly, you'd get a lovely 404 message. Technically, this error code isn't correct. They should be using 401[6] as you haven't provided any credentials yet. To provide some credentials, add ?key=<API_KEY> to the end of the link (or URL)[7] and we should get some data back. Depending on what browser you're using, this might look a bit different but as I'm using Firefox[8] it has built in JSON formatting (I can totally recommend it, especially in light of Google[9] being[10] evil[11] recently[12]). All JSON code will be shown like the example below:

  {
    "this_is": "some_json",
    "heres_a_string": "string",
    "heres_an_integer": 1,
    "heres_a_boolean": true,
    "heres_a_double": 3.14159,
    "objects_are": {
      "like": "this",
      "and_this": 1,
    },
    "finally": [
      "heres",
      "some",
      "arrays!"
    ],
    "you_get": "the_idea"
}

Anyways, if we go to /player?key=a78376cb-3c0f-4fe0-8067-251afccca692, we get the following:

  {
    "success": false,
    "cause": "No \"name\" or \"uuid\" field!"
  }

Oh, that didn't work. Hmm, let's take a look at the output shall we?

  "success": false,

This obviously means that the request that we made failed, and we can see that:

  "cause": "No \"name\" or \"uuid\" field!"

There was no "name" or "uuid" field that was sent with the rest of the request. Okay, interesting.

We can see that these errors that we're getting are actually pretty self-explainatory. We haven't supplied a name or UUID, so the program freaks out and crashes. This is because the name/UUID field and the key field are mandatory fields. Different APIs will give you different mandatory fields

Going back to our query, if we add in the name or UUID field then we should get what we want. I'm going with name for readability, but I'd recommend you go with UUID as they're unique to the end user's account. I can change my name, but I can't change my UUID. To add further arguments to your query, you might think that you'd need to go to /player?key=a78376cb-3c0f-4fe0-8067-251afccca692?name=Natfan, but in fact this won't work. This is because you need to use the & symbol instead. If we go to /player?key=a78376cb-3c0f-4fe0-8067-251afccca692&name=Natfan, then we get the following:

  {
    "success": true,
    "player": {
      "_id": "5222482f0cf29e275fd355e2",
      "achievements": {
        "arena_bossed": 33,
        "arena_climb_the_ranks": 1034,
        "arena_gladiator": 33,
        ...

Woot, we've made our first API call to the Hypixel API, and got a response back. Let's take a little breather and go a little more in depth on what we just learnt.

Step III: Understanding HTTP

Going back to those mandatory fields we learn about in Step II, let's try to put this into a real world example to give them context.

Let's say that Joe Bloggs (referred to as "$customer" in the following example) decides that that really have a craving for McDonald's. other fast food restaurants are available

They walk up to the counter the following interaction happens:

    $customer: Hi! I'd like a burger please.
    $cashier: Right, what kind of burger would you like?
    $customer: Just a burger, you know?
    $cashier: I'm sorry sir, I'm afraid I'm unable to give you "just a burger, you
    know". Please be more specific.
    $customer: I'd like a cheeseburger, please.
    $cashier: Very good, and could I please have your credit card details so that you
    can pay for this?
    $customer: What? No. Just give it to me for free.
    $cashier: I'm sorry sir, but both the thing you want to order and how you're going
    to pay for it are mandatory requirements for this transaction.
    $customer: Fine, my credit card number is 123456789.

That was a pretty painful encounter, right? If the customer had just told the cashier what they wanted in the way that the cashier wanted it, then that whole conversation would have been much shorter. See the following:

    $customer: Hi! I'd like a cheeseburger and my credit card number is 123456789
    $cashier: Excellent, I'll ring that up for you now.

See, much better. I know that seemed like a bit of a tangent, but I'm trying to show that if you tell the server (or cashier in our example) exactly what you want in a format it expects, you should get it right on the first try.

I know that learning about the inner workings of URLs sounds a little dull, but I really think that understanding how the HTTP Protocol tautology, anyone? is super useful and can help with understanding how the Internet works!

Let's go with an example, and ask the browser to run that query that was successful at the end of Step II:

  1. Right, browser: I'm going to ask you a question and I want a result.
  2. The protocol that we want to use is the HyperText Transfer Protocol (Secure)
  • https://
  1. The subdomain we want to use is called "api"
  • https://api.
  1. And the domain we want to use is called "hypxiel.net"
  • https://api.hypixel.net
  1. When you're there, go to the path "/player"
  • https://api.hypixel.net/player
  1. Oh, now add some queries so prepare the URL to receive those
  • https://api.hypixel.net/player?
  1. The first query we want to add is our API key, so let's add that in
  • https://api.hypixel.net/player?key
  1. And we need to make sure that key is set
  • https://api.hypixel.net/player?key=a78376cb-3c0f-4fe0-8067-251afccca692
  1. Now let's add another query
  • https://api.hypixel.net/player?key=a78376cb-3c0f-4fe0-8067-251afccca692&
  1. And let's make sure that the query we're looking for is called 'name'
  • https://api.hypixel.net/player?key=a78376cb-3c0f-4fe0-8067-251afccca692&name
  1. Finally, we want to make sure that 'name' query is a player's name
  • https://api.hypixel.net/player?key=a78376cb-3c0f-4fe0-8067-251afccca692&name=Natfan

Right, that was quite a lot of information to pack into such a small space, but that's why I love URLs. For more information on how these bad boys work, check out doepud's article on the Anatomy of a URL[13]

Step IV: Working with the API in PHP

So before we get started with this, I'm just going to go out and say it: I like PHP. Sure, it has it's quirks, but at the end of the day it's a very well written language with lots of internal consistency easy language to get started in. In fact, let's take a look at the following code so that you can see how damn each it is!

  <?php
    $key = "a78376cb-3c0f-4fe0-8067-251afccca692";
    $url = "https://api.hypixel.net/player?key=$key&name=Natfan";
    $json = file_get_contents($url);
    $data = json_decode($json, true);
    print_r($data);
  ?>

So, if I plug that into a file on my PHP-enabled Apache2 web server (the one hosting this blog, actually) we should get the following output:


Bibliography/Links

[1] : https://natfan.io/hypixel = My statistics website and the reason why I'm making this post.
[2] : https://i.natfan.io/PristineGroundedHerald.jpg = The API key image, so that you know what I'm talking about.
[3] : https://github.com/HypixelDev/PublicAPI/tree/master/Documentation/methods = The official repository for the Hypixel API, which include documentation. That's handy!
[4] : https://github.com/HypixelDev/PublicAPI/blob/master/Documentation/methods/player.md = Information about the /player endpoint, the one that this blog is all about.
[5] : https://api.hypixel.net/player = The link to the /player endpoint, used to access information about players on the server.
[6] : https://httpstatuses.com/401 = More information about the 401 HTTP status code. I love this site, it's so useful!
[7] : https://en.wikipedia.org/wiki/URL = Information about what a URL is, if you don't already know :)
[8] : https://firefox.com = Mozilla's Firefox browser, made by a non-for-profit organisation that has a (mostly) clean track record with privacy, plus kick-ass features like JSON formatting baked in!
[9] : https://www.engadget.com/2018/05/24/google-will-always-do-evil/ = See #12.
[10] : https://en.wikipedia.org/wiki/Don%27t_be_evil#Use_in_criticism_of_Google = See #12.
[11] : https://futurism.com/google-dont-be-evil = See #12.
[12] : https://supchina.com/2019/03/06/is-google-still-developing-a-censored-search-engine-for-china/ = Google has been being a mite shifty recently, see links 9-12 for some context. I'll try to keep politics out of this, but I'm trying to de-Google myself a bit more these days...
[13] : https://doepud.co.uk/blog/anatomy-of-a-url = Pretty decent page with lots of information crammed into a small space. A lot like the thing it's talking about, really.

key = a78376cb-3c0f-4fe0-8067-251afccca692