NML Blog

Recent posts

Easy APIs and MVPs

Think about this…

Many of the biggest social-tech companies – like Facebook, Twitter, Soundcloud, Tumblr and Instagram – have brought out (web) APIs in the last couple of years. They have a strong business incentive to do so: their APIs provide developers access to their valuable user data, through a properly authenticated app, of course. In return, they have people building services and apps using their data & services.

The rewards are clear for the 3rd party app-developer too. Using a “parent” company’s API lets a developer leverage off massive amounts of existing user-generated content and data to build something niche, smart and useful. However, there is at least one big risk to 3rd-party developers here: their app’s very functionality depends on the API-provider continuing to support it.

Then came The Mashup: one app, many APIs…

A mashup is an application built using data from various sources, obtained via those sources API’s, and which renders a combination – or new form of data – based on its sources. One of the more modern approaches to consuming a web API’s data is through an architectural principle known as REST (Representational State Transfer) – where a representation of an object’s data is returned to the requester, and filtered accordingly. This is a newer take on API-access, compared with the older SOAP (Simple Object Access Protocol) communication protocol. However, this post is not a SOAP vs REST discussion. But I will say that I’ve used both, and REST was much simpler to use. This simplicity is probably why its popularity is only growing.

But the proof is in putting it to the test…

So, in building a little proof of concept the other day I had the chance to play with some of these technologies. My colleague was to build the UI for an Android app, using Xamarin. I agreed to look at the service calls. The app is essentially a mini-foursquare, built using Foursquare’s API. (Four-ception?)

From a functional point of view the idea was to keep it ultra-simple. The user would be presented with a simple list of points of interest nearby, filtered according to predetermined criteria: type of location (e.g. food, coffee, sushi); distance from the user; popularity etc. As the user moves, the list would update accordingly. Although, having just read this article we’re definitely considering scrapping lists in favour of cards.

Architecturally speaking we decided to go with Xamarin and a REST-oriented approach to obtaining our data. Initially the points of interest would be built up using Foursquare’s API – specifically a call to the Venues endpoint, and more could be added later. The UI & overall app structure would be built using an MVVM (Model View ViewModel) approach.

We browse to https://developer.foursquare.com/, hit “Get started”, and (after a little bit of reading) make our way to their Venue search documentation. After registering our app with Foursquare we have access to a Client ID & a client Secret Parameter. We’ll need these for our API calls. The structure of the venues explore endpoint at Foursquare is as follows:

https://api.foursquare.com/v2/venues/explore is the base address to which we make our call. However, we also need to pass in several query string parameters in the HTTP GET request – like some of these:

Foursquare's Explore endpoint's parameters

Foursquare’s Explore endpoint’s parameters

So, we grab the base URL for the endpoint off of the site, and create a HTTP GET request that looks something like the following:

var url = string.Format("{0}{1}?{2}&{3}&{4}&{5}&{6}&{7}&{8}&{9}&{10}",  
  "https://api.foursquare.com", 
  "/v2/venues/explore", 
  "client_id=XXXXXXXXX", 
  "client_secret=YYYYYYYY", 
  "v=20131016", 
  "ll=-33.933706%2C%2018.453813", 
  "llAcc=100", 
  "radius=5000", 
  "section=food", 
  "limit=10", 
  "novelty=new");

Great stuff. For demo purposes we now have the URL we want to make a request of. We can test this over at Apigee’s API console site (https://apigee.com/console/foursquare ) if we like. After signing up, signing in, and allowing access to our Foursquare account we can now use their service to mock calls to various API-providers. (There’s a lot of them!)

So, this URL now returns us an HTTP status code of 200 (OK) and a JSON response containing our data.

That’s all good. But how do we now get this data into our code in a way we can work with? The JSON to C-Sharp site provides a handy web-based way of generating the C# classes we would need in order to deserialize the data. (Well, this is one way of doing it anyway). We simply copy+paste the sample response data into the site, and voila: corresponding C# classes. Another way of achieving this is to copy the sample JSON data and use Visual Studio’s “Edit -> Paste Special -> Paste JSON As Class” option.

Okay, we have the URL structure and classes ready to hold the de-serialized JSON data. We just need to make the HTTP GET request and de-serialize the data. The following snippet shows a handy generic method that will do both these tasks for us.

public class JsonHelper {  
    public static T DownloadSerializedJsonData < T > (string url) where T: new() {
        using(var w = newHttpClient()) {
            var json_data = string.Empty;
            // attempt to download JSON data as a string
            try {
                using(StreamReader reader = newStreamReader(w.GetStreamAsync(url).Result)) {
                    json_data = reader.ReadToEnd();
                }
            } catch (Exception) {}
            // if string with JSON data is not empty, deserialize it to class and return its instance 
            return !string.IsNullOrEmpty(json_data) ? JsonConvert.DeserializeObject < T > (json_data) : new T();
        }
    }
}

In hindsight, I suppose it should really be called DownloadAndDeserializeJsonData if we’re going to attempt to stick to the method naming conventions put forth by Robert Martin in his excellent book “Clean Code, A Handbook of Agile Software Craftsmanship”. On that note, it should probably be split up a bit into at least those two separate functions. But for this demo, it’ll do!

As it stands, we can call the above method, passing in a string URL and a (dot)NET object of Type T. This lets us re-use the method for any type of JSON request to Foursquare’s API, and will make its data available to us in the form of a (dot)NET class which matches the JSON data.

We now call the above method as follows, passing our URL in:

var asyncResult =JsonHelper.DownloadSerializedJsonData<VenueResult>(url);  
VenueResult venues = asyncResult;  
List<PointOfInterest> pois = ClassMapper.MapVenuesToPois(venues);  

Here, VenueResult is a class matching the JSON data structure coming back from Foursquare, and PointOfInterest is our own, smaller, version of this class. We build a little mapper which transforms a VenueResult to a PointOfInterest and pass that back to our UI.

VenueResult is about 300 lines long, which is 300 lines too long for this post, but you can get your own class matching the incoming JSON data if you follow the steps above.

For the curious, PointOfInterest & the ClassMapper are below:

PointOfInterest.cs:

// Put your code here and then press the button
public class PointOfInterest {  
    public int Id {
        get;
        set;
    }
    public string Name {
        get;
        set;
    }
    public string ImagePath {
        get;
        set;
    }
    public int CheckIns {
        get;
        set;
    }
    public string Description {
        get;
        set;
    }
}

ClassMapper.cs

public class ClassMapper  
    {
        public static ListMapVenuesToPois(VenueResult venueResult) 
        {
            var venues = venueResult.response.groups
                .Select(groups => groups.items)
                .Select(items => items.Select(venue => venue.venue));
            var photoPath = venueResult.response.groups.FirstOrDefault().items.FirstOrDefault().tips.FirstOrDefault().photourl;
            var mappedResult = venues
                .SelectMany(venue => venue)
                .Select(item => new PointOfInterest 
                {
                    Id = new Random().Next(), Name = item.name, Description = "TODO ... find a description", CheckIns = item.stats.checkinsCount, ImagePath = photoPath
                })
                .ToList();
            return mappedResult;
        }
    }

Wasn’t that easy!

Thank you, Mashups.

Need a software development partner?

Get in touch