116 heroes and counting
This section will have us start making calls to the Dota 2 API provided by Steam. We'll begin with a fairly straightforward call to GetHeroes
, which will return a list of all available heroes in Dota at the moment. Then, we can use the data that we get in response and a URL for images to display hero portraits. Let's start with a simple GET request to the following URL:
https://api.steampowered.com/IEconDOTA2_570/GetHeroes/v0001/?key=APIKEY
As noted previously, replace APIKEY
with your own API key or the variable storing it. We can use it in our server-side code, as detailed below. This request also takes the common options listed in the Getting Started section.
An example follows of how the JavaScript might look if using Node.js, Express, and Express Handlebars. You can use this as a template for your GET requests. This example will simply put a huge wall of text (the JSON object as plaintext) on a page named test
and prints the JSON response to the console, which isn't of much use to us right now, but we can tweak it down the line for our purposes, which we will see at the end of this section. For this sample code, your test.handlebars
should have {{stuff}}
in it. You can store your API key outside of the function as a string global variable.
The result is a list of all 116 current heroes. For those that have played the game for a while, that Skeleton King is still Skeleton King (THE ONE TRUE KING), despite Valve changing his in-game name to Wraith King (for pressing ceremonial reasons).
For fun, let's try using the language option (one of the common options outlined above) to get the heroes in Simplified Chinese (using zh_cn
for the language).
https://api.steampowered.com/IEconDOTA2_570/GetHeroes/v0001/?key=APIKEY&language=zh_cn
The result now includes a localized name (in Simplified Chinese) for each hero! Tiny is literally "little little".
The response is fairly straightforward, and there aren't a lot of different keys to deal with in the response object. Here's a breakdown of the response that we get:
result
heroes
name
: The hero's in-game tokenized string nameid
: The hero's IDlocalized_name
: The language-specific name of the hero for displaying the name; this field is not included if a language is not specified in the API callstatus
: Status of the API callcount
: The total number of heroes in the list
Using the information from our response from GetHeroes
, we can get hero portraits from Valve's servers. The URL for the images follows the following format:
http://cdn.dota2.com/apps/dota2/images/heroes/HERONAME_SUFFIX
Replace HERONAME
with the name of the hero obtained from the response to the GetHeroes
call, but with the prefix npc_dota_hero_
removed. For example, use witch_doctor
instead of npc_dota_hero_witch_doctor
.
Replace SUFFIX
with one of the four following options:
sb.png
: 59x33px small horizontal portraitlg.png
: 205x105px large horizontal portraitfull.png
: 256x144px full-quality horizontal portraitvert.jpg
: 235x272px full-quality vertical portrait (note that this is a .jpg)
Armed with our JSON response and a URL for images, let's combine what we know and display small horizontal portraits for all the heroes. Using our example_request.js
from above, let's modify it to append images for each hero to an array, which can then be displayed on the page called test
. Note that we have parsed the response body using JSON.parse(body)
. We then go through the list of heroes and get the hero name by stripping off the npc_dota_hero_
prefix, then adding the HTML img
tag to the array. Our test
page should have the following lines in it: {{#each dataList}} {{{this}}} {{/each}}
; note the use of three curly braces for {{{this}}}
, which will render the HTML img
tags. The end result is a colorful block of small horizontal hero portraits.
While we can make a GET request every time we want load our page with the hero images, since we know that the list of heroes changes very infrequently (thanks, Valve), it's probably best to refrain from making unnecessary requests to the API. To avoid making extra calls, I saved the JSON response of all the heroes from one API call and saved that on my server as a separate JSON file, from which I can get the data to use in future functions. However, if you know that the request you're making has the potential to have different responses depending on when you're calling it (such as when we make calls later to GetMatchHistory
), and you want your page to stay up-to-date, you may need to make API calls every time your page is loaded. Another option would be to make the API call outside of the call to app.get()
, so that the call is made only one time every time the script is run (such as when you start your server).