Realm APIs Unneededly Complicated

This is just some feedback that doesn’t amount to a real hill of beans, but I just finished moving my dumb little realm status checking site ([https://]isthereaqueue[.]com) from the old WoW Community API over to the new Game Data and Profile APIs, and I wanted to let you know about my experience.

I don’t know who was in charge of the transition from moving /wow/realm/status over to the collection of [data/wow/realm/index, /data/wow/realm/{id}, /data/wow/connected-realm/index, /data/wow/connected-realm/{id}], but my goodness y’all complicated that for absolutely no reason.

Either I’m missing something completely, or the fact that I have to get the realm list, then get the connected realm list (just to find out if the realm I’m interested in is even gonna show up when I query /connected-realm/,) have to check the realms that are the connected ones by looking at freakin’ hrefs rather than IDs just to get the data that fit just fine on a single endpoint before.

For as nice and developer friendly as the community APIs were, these new ones are certainly not. (At least from the prospective of the one data point I wanted.)

I do want to say that I appreciate being able to get all of the localized strings in a single go. That’s pretty nice.

And lastly: letting the form post editor here automatically link URLs and even putting a button on the dang toolbar, only to let me know I can’t include URLs in my form post is a pretty jerk move.

4 Likes

Hi Rhox.

First let me say I understand your frustration and I agree it does seems over complicated at first, but I’ll share my perspective as a developer who is always working with APIs both developing and consuming them.

That is just not true. There is always a reason for big changes like that. I can’t tell exactly the reason Blizzard developers had to do this. What I can do is enumerate some of the most common reasons.

1. Maintainability

It is a lot easier to introduce changes on well written and properly segmented API. This leads to the next item: stability.

2. Stability

A modular API allows new features to be introduced on new endpoints instead of modifying already existing ones, this means you are less likely to break something that was working before just to add a few more fields to response payload.
Lets say when Shadowlands comes out items will have a new trait system and it requires more information to be loaded on the back-end of the API. What options do you have ?

  1. Add a few items that will always return null for older existing items.
    There is nothing wrong with that, but sometimes it is hard to cover all kinds of items from previous expansions so there is a risk to break something that used to work before.
  2. Add a new endpoint just for retrieving trait information.
    In this case the new endpoint won’t affect the old one and if there is a bug only apps consuming the new endpoint will be affected instead of all other community created applications.

3. Dependencies

Sometimes you create separate endpoints just for integrating different system and micro services into a single API.

Lets say the realm list is acquired from a database while the actual status are obtained from an internal API. Should a defect on one of those services affected all responses from the API ?

4. Standards and Design patterns

When you work with a large number of teams and co-workers it is highly recommended to have a single standard to rule how you structure your code. This helps preventing code smells, variable performance across the services, and so on.
Sometimes it seems some endpoints could be joined into just one, but by doing so you would nod comply to some rules.

5. Many more

There are lots of reasons for changes like this, some of them might even depend on the programming language and infrastructure they are using.


I’m sorry for the long text but a lot of people seems to have the same feeling about the new endpoints so this post might help a little. All I want is to show is how some things are not always as simple as it seems at first.

Keep in mind Blizzard is one f the largest game publishers, a LOT of awesome applications and people use the API every day. Whatever their real reasons were to make those changes most likely is an effort to make it easier for them to keep delivering new data faster and minimizing the risk of the API letting us down due to technical problems.

Also keep in mind the API allows for 100 call per second, you can most likely fetch all realms in less than 3 sec if your code is well written using asynchronous calls. If you need advice on how to implement such things try asking around over the Community Discord Server

More important Blizzard developers are awesome and they do listen to the API community as you can see in this thread. Just make sure to carefully explain why some chances are needed and - when possible - propose solutions.

Hi Schiller. I’m gonna respond to your post bit by bit. Obviously this is just my opinion and doesn’t matter in the scope of things, but here we go anyways.

I’m in development and operations in my day job as well. My company is nowhere near the size of Blizzard, but I’ve had my hand in producing and consuming APIs both large and small as well.

I’ll concede that there’s always a reason. They clearly wanted to get away from their Mashery API. I’m not sure if that’s because they changed the backend and felt it was the right time, thought they were overpaying for the Mashery platform, wanted to bring it all in house, or what have you, but on the surface it definitely appears to be along that line.

I agree. I also however feel like the mastery API was pretty decently segmented. I didn’t have familiarity with all of the endpoints, but in the areas I touched (realm status, character & item information, and bits and pieces of others).

There were certainly a few rough edges (eg. things like the relic weapon/azerite neck system), but that seemed to be less of an API design flaw and more of data representation issues. (It felt very much like we were getting a peek directly at server variables with the way it just returned mostly undocumented ‘bonusIDs’ for the relics, and such.) I haven’t so much as started looking at the new character endpoints, as it seems I’m going to have to do the same hoop jumping that I did for realms with them, looking up arbitrary IDs first, then making requests about the characters, which seems incredibly redundant to me, seeing as realm+character name is unique to start with. I digress.

Sure, you can have this one completely. Add new endpoints, I’m all for that. Or add new query parameters or header values (like they’ve done with the ‘Battlenet-Namespace’ header now), on the same endpoints that modify or add to the response. But their move from the Mashery API to this one was far more than tweaking a few responses or adding a few endpoints. It completely changed the flow of how you interact with them. Sure, long term stability is definitely a goal, but in this move they completely invalidated every single API consumer out there that hasn’t been re-worked to handle this different API. That’s sorta the opposite of stability, if you ask me.

Honestly, the way the API is structured, yes. Currently broken into four endpoints, they boil down to something like this:

  • /realm/index - Get the list of realms, some cursory information about them, and their IDs. (Essentially, name, id, and ‘slug’ which appears to be a non-I18N handled name and is actually quite handy. Realm ID seems almost useless, but more on that later.)
  • /realm/<realmSlug> - Get more detailed information about the particular realm. Like if it’s a normal or pvp server, the timezone it’s in, and so on. If the realm status were given to me here, I wouldn’t have made a peep, because it would have made sense to me to find it here. Instead, there’s also a connected_realm key, which has a single object that has a single key inside it, href.

Let’s take a look at this href. Here, I picked one for the NA server Stormrage: https://us.api.blizzard.com/data/wow/connected-realm/60?namespace=dynamic-us

Why, that’s an API call it’s referencing there! It’s not documented what the href is supposed to mean, but heck, lets call it anyways.

BINGO, there’s the data I wanted in the first place, moved to this connected-realm/<connectedRealmID> endpoint. But now I’ve got this data separated out on this other endpoint, because… reasons? If I try to look up a server that isn’t a server that has a direct mapping to the connected-realm endpoint, then I have to first make a call to realm/<slug> just to see if the href it points at is different?

Now, would this be so bad (if it were documented?) No, not terribly. I mean its considerably more API calls than I needed to make in the past, but whatever. But why on earth does the realm/slug API just point me to another API? The other API doesn’t give a whole heap of data (some of which its just repeating from the realm API!) Just get the data and give it to me there, don’t make me make another call. It’s gonna take considerably more resources for handing another entire request from me calling externally than it would be for the API to just resolve it internally and give it back to me. Or even better, let me tell realms/slug that that’s my goal, so it can be smart and add that data in the first place, and not waste it’s time for someone who isn’t interested.

There’s about two sentences in the documentation that describe the href object, as a “link”, that they claim is to “increase discoverability”

I got way off track here rambling about trying to figure out what I was supposed to call with the anemic documentation, but my point is still yes: I absolutely would expect a call to an API that gives realm information to be affected by any backing service. Yes, there are lines that should be drawn and separated (your example about shadowland specific traits was a good one), but why the heck I would need three API calls to get what I would consider basic information about a server seems exceedingly excessive.

Sure. And the move to OAuth is a very good one. We’re still not hmac-ing requests, but hey, one standard at a time I guess.

If these new APIs are some sort of standard (and maybe they are, all the responses have headers that reference some sort of blizzard specific schema… that I can’t find documents anywhere…), then I’m willing to go on the record to say it’s a rough one that needs a revision.

A line in the introduction of the documentation says:

Game data and profile APIs return JSON documents directly to the consumer in the exact format and structure they are stored. […]

First reading that, it read like it was meant to simplify the API. Having interacted with the API, I now believe it to be “because it was easy”. To me, it feels like it was the path of least resistance to get the game systems team’s data available to the API. Probably something to the tune of “just publish your data here, and it’ll be available in the API”. Which explains the anemic documentation, as it’s probably all just generated via metadata.

Counterpoint: Microsoft still supports APIs they introduced in Windows 1. No, they’re not all that pretty, and yes, it’s definitely been a pain for them to do so, but that sort of compatibility over decades is what gives Windows the sticking power it’s always had. Changing the API like Blizzard has here completely broke every application and tool that hasn’t updated, and I bet there’s lots that won’t be, too. And that’s pretty unfortunate. If their reasoning is ‘technical problems’, well they’re off to a rocky start, because they were down for several hours the other day already, so they already blew their shot at four nines this year :stuck_out_tongue:

If I told my boss I was going to replace an endpoint that users could hit to grab all of info XYZ with two endpoints so they’d have to hit the first one to get X, and then the second one two hundred and fifty times to get all the Ys and Zs, he’d tell me I’m mad.

He’d think I’m even more crazy when I tell him that I want this information to be fresh, so I’m gonna update it every 30 seconds or so, too.

I wanted to close with this one to touch on what you said here: a lot of people seem to have the same feelings about the new endpoints. You know how they say: “Once is a fluke. Twice is a coincidence. Three times is a pattern.”


I don’t mean to come at you guns blazing, Schiller. But I wanted to articulate my frustration in a way that responded to your points. Like I said at the top, being in software & ops myself, I get how these things work a lot of times, and they aren’t always done the way the people on the inside nor the outside wish they were.

I also know, that only the squeaky wheels get the grease.

6 Likes

There is a reason for that. These new endpoints are not user-friendly. I need for example to retrieve Realm name and status for our guilds website. This is something I develop and manage for our guild in my spare time. Key words there are “Spare Time”! I would wager that most of the external API requests that Blizzard receives are from similar hobbyist types.

I don’t have many complaints about the rest of the APIs, but this one needs tended to. This is ridicules. I develop REST APIs for credit card processors and related hardware so I have a notion as to what constitutes a good API for circumstances such as this, and this implementation isn’t it.

It actually seems geared to discourage hobby enthusiasts from working with it at all and probably has in the end.

2 Likes

Exactly, Kevin.

The APIs I run definitely don’t operate on as much data as Blizzard has, nor are they likely used by as many folks, but we try exceedingly hard to ensure they’re logical and straightforward to use.

This API feels like it’s a really thin layer that someone taped on top of a query and decided to ship. I mean, the (giant air quotes) documentation for the connected realms endpoint says, and I quote

Returns an index of connected realms.

That’s it. That’s the documentation, in it’s entirety. That screams auto-generated and ignored. Returns the $parameter of $endpoint.

Okay, fine, not the first time I’ve dealt with bad documentation before.

But the key/href objects in the responses. Which they claim is to “increase discoverability”? That’s what really gets me. Discoverable for who? That is so disconnected from what an API is supposed to be that it’s almost baffling. Like, I have to assume the intent is to do something like the HATEOAS principle behind REST APIs. Except that the intent of that is to have a client that could dynamically dig it’s way through an API by performing named actions on data. Where as these endpoints just respond with “This is a related link!” That’s not actionable, dynamic, or even purposeful really.

Them’s big-time smells, imo. Maybe was there as some part of the development process, to debug that links are working the way they expect, and it was supposed to be more?

Lets take a look at a response even!

{
  "_links": {
    "self": {
      "href": "https://us.api.blizzard.com/data/wow/connected-realm/?namespace=dynamic-us"
    }
  },
  "connected_realms": [
    {
      "href": "https://us.api.blizzard.com/data/wow/connected-realm/4?namespace=dynamic-us"
    },
    {
      "href": "https://us.api.blizzard.com/data/wow/connected-realm/5?namespace=dynamic-us"
    }
}
(trimmed, because I've no need to spam.)

First, you told me the endpoint that I? called? I’m the one who made the call, why are you telling me? Next, connected_realms, okay, that’s a fair name. I did call the connected-realms endpoint… and it’s a bunch of objects with a single key each named href?!

Oh, wait, there’s an interesting header, Battlenet-Schema: connected-realm, okay, a schema, that’ll help. Except… it doesn’t. They’re not documented. They’re not even defined. The intro to the API docs says:

Game data and profile APIs allow Blizzard to share game information via a single, well-defined interface in an easily-consumable format that has an agreed-upon schema between publisher and consumer.

Doesn’t seem that well defined to me. Agreed on by whom?

What if I think, well forget all that, and decide to just call those silly little hrefs anyways! Whoops, another pitfall!

As the World of Warcraft team continues to develop and release new data into the Game Data and Profile APIs for World of Warcraft, there might be times where a JSON response document links to a child JSON document that is:

  • protected by a private scope and has not yet been released for public consumption.
  • not yet published.

In these cases, a request to the child resource returns a 404, 401, or another appropriate status code and response.

They may not even work. And what’s more than that, they may fail with errors that look like transient or application caused errors! In fact you may end up telling my application that it’s unauthorized to check out the link you just handed it? Seriously? Worse still, 401 implies that authorization is possible! At least use 403 if you want to just slam the door, despite showing me that the door exists.

But here, I’ll give you this bit for free: 405 Method Not Allowed. It’s literally a response code for “I don’t want you to do that.” I’d even not blink at a 503 Service Unavailable, with a Retry-After of next month.

Maybe I’m just becoming more of a curmudgeon in my age, but call me crazy to think I like my APIs to make sense and be approachable.

But my goodness, get an intern to write a few lines of documentation and publish a schema or two.

3 Likes