Using a REST API with Unity Part 1

Denny and Travis Scott

June 24th, 2015

Introduction

While developing a game, there a number of reasons why you would want to connect to a server. Downloading new assets, such as models, or collecting data from an external source is one reason. Downloading bundle assets can be done through your own server, which allows your game to connect to a server and download the most recent versions of bundle assets.

Suppose your game also allowed users to see if that item was available at Amazon, and for what price? If you had the sku number available, you could connect to Amazon's API, and check the price and availability of that item. The most common way to connect to external API's these days, is through a RESTful API.

What is a REST API

A RESTful api is a common approach to creating scalable web services. It provides users with endpoints to collect and create data using the same HTTP calls to collect web pages (GET, POST, PUT, DELETE). For example, a url like www.fake.com/users could return a JSON of User data. Of course, there is often more security involved with these calls, but this is a good starting point.

Once you begin understanding REST API's, it becomes very second nature to query them. Before doing anything in code, you can try a query! Go to the browser and go to the url: http://jsonplaceholder.typicode.com/posts. You should be returned a JSON of some post data. You can see REST endpoints in action already. Your browser posted a GET request to the /posts endpoint, which returns all the posts. What if we want just a specific post? The standard way to do this is to add the id of the post next. Like this: http://jsonplaceholder.typicode.com/posts/1. You should get just a single post this time. Great!

Often when building Unity scripts to connect to a REST endpoint, we'll frequently use this site to test on, before we move to the actual REST endpoints I want!

Setting up your own server

Setting up our own server is a bit out of the scope of this article. In previous projects, we've used a framework like Sails JS to create a Node Server, with REST endpoints.

Parsing JSON in Unity

Basic REST

One of the worst parts of querying REST data is the parsing in Unity. Compared to parsing JSON on the web, Unity's parsing can feel tricky. The primary tool we use to make life a little easier is called SimpleJSON. It allows us to create JSON objects in C#, which we can use to build or read JSON data, and then manipulate them to our need. We won't be going into detail on how to use SimpleJSON, as much as just using the data retrieved from it. For further reading, we recommend looking at their documentation. Just to note though, SimpleJSON does not allow for parsing of GameObjects and such in Unity, instead it deals with only more primitive attributes like strings and floats.

For example, let's assume we wanted to upload a list of products to a server from our Unity project, without the game running (in editor). Assuming we collected the data from our game and its currently residing in a JSON file, let's see the code on how we can upload this data to the server from Unity.

string productlist = File.ReadAllText(Application.dataPath + "/Resources/AssetBundles/" + "AssetBundleInfo.json");
    UploadProductListJSON(productList);

    static void UploadProductListJSON(string data) {
        Debug.Log (data);
        WWWForm form = new WWWForm();

        form.AddField("productlist", data);
        WWW www = new WWW("localhost:1337/product/addList", form);
    }

So we pass the collected data to a function that will create a new form, add the data to that form and then use the WWW variable to upload our form to the server. This will use the POST request to add new data. We normally don't want to create a different end point to add data, such as /addList. We could have added data one at a time, and used the standard REST endpoint (/product). This would likely be the cleaner solution, but for the sake of simplicity, we've added an endpoint that accepts a list of data.

Building REST Factories for In Game REST Calls

Rather than having random scripts containing API calls, we recommend following the standard web procedure and building REST factories. Scripts with the sole purpose of querying rest endpoints. When contacting a server from in game, the standard approach is to use a coroutine, as to not lock your game on the thread. Let's take a look at the standard DB factory we use.

private string results;

        public String Results {
            get {
                return results;
            }
        }

        public WWW GET(string url, System.Action onComplete ) {

        WWW www = new WWW (url);
        StartCoroutine (WaitForRequest (www, onComplete));
        return www;
    }

        public WWW POST(string url, Dictionary<string,string> post, System.Action onComplete) {
        WWWForm form = new WWWForm();

        foreach(KeyValuePair<string,string> post_arg in post) {
            form.AddField(post_arg.Key, post_arg.Value);
        }

        WWW www = new WWW(url, form);

        StartCoroutine(WaitForRequest(www, onComplete));
        return www;
    }

    private IEnumerator WaitForRequest(WWW www, System.Action onComplete) {
        yield return www;
        // check for errors
        if (www.error == null) {
                    results = www.text;
            onComplete();
        } else {
                    Debug.Log (www.error);
                }
    }

The url data here would be something like our example above: http://jsonplaceholder.typicode.com/posts. The System.Action OnComplete is a callback to be called once the action is complete.

This will normally be some method that requires the downloaded data. In both our GET and POST methods, we will connect to a passed URL, and then pass our www objects to a co-routine. This will allow our game to continue while the queries are being resolved in the WaitForRequest method. This method will either collect the result, and call any callbacks, or it will log the error for us.

Conclusion

This just touches the basics of building a game that allows connecting and usage of REST endpoints. In later editions, we can talk about building a thorough, modular system to connect to REST endpoints, extracting meaningful data from your queries using simple JSON, user authentication, and how to build a manager system to handle multiple REST calls.

About the Authors

Denny is a Mobile Application Developer at Canadian Tire Development Operations. While working, Denny regularly uses Unity to create in-store experiences, but also works on other technologies like Famous, Phaser.IO, LibGDX, and CreateJS when creating game-like apps. He also enjoys making non-game mobile apps, but who cares about that, am I right?

Travis is a Software Engineer, living in the bitter region of Winnipeg, Canada. His work and hobbies include Game Development with Unity or Phaser.IO, as well as Mobile App Development. He can enjoy a good video game or two, but only if he knows he'll win!

Get your free eBook today

Continue on your journey as a game developer by deciding which game engine and language suits you best with the help of our free eBook.