APIMASH: Using API’s to create compelling Windows Apps

APIMASH is the name is a project currently undertaken by Technical Evangelists here at Microsoft to provide a portfolio of starter kits that leverage well known API’s such as TwitterEdmunds, Tumblr and many others in order to inspire you, yes you, to create compelling Windows 8 and Windows Phone apps.

Download the APIMASH Starter Kits today and get started.

As I have worked with developers over the past year to develop Windows apps, I often hear the refrain ‘I want to build an app but I just need an idea’ or ‘I have an idea but I don’t know how to get started’. That’s where the APIMASH Starter Kits come in. They are fully functional Windows 8 apps that make asynchronous calls to well known API’s, deserialize the JSON or XML payloads to construct data models and map those data models to view models for binding to UI controls. They demonstrate the entire sequence of calls and mappings necessary to get data from the Internet and onto the screen. What’s left as an exercise for the developer is to customize the API calls, mash those calls together if appropriate and dress up the UI to dazzle and impress.

This article provides a primer to investigating the wonderful world of Internet API’s and the patterns and practices of invoking these API’s from Windows. Future articles will dig into specific APIMASH Starter Kits.

The Wonderful World of API’s

There are thousands of API’s, public web services, available to developers to leverage to create apps. You can get a sense of the size of this sandbox by visiting sites such as the Programmable Web and APIHub.com. You will quickly see that there are LOTS of API’s to investigate and draw inspiration from to create a great app.

Be aware not all API;s are created equal. Spending some time to validate API’s of interest is well served. Most APIs require the developer to register and request a Developer Key. Some API’s are throttled, limited to a certain number of calls a day or second. Many are free but some are not. Here is a list of criteria that you can use to validate API’s of interest:

  • Developer Key Required
  • API protocol – REST or SOAP?
  • Authentication Required – OAuth, SessionID, etc.
  • Performance – how well does the API perform?
  • Service Level Agreement (SLA) – is the API always available?
  • Payload format – JSON, XML, other
  • Throttled – If yes what is the limit?
  • Free or Pay
  • Is the API mashable – can the data be used as input to another API?

Last but not least is to read the Terms and Conditions of the API provider. The details of how often you can call the API and other usage rules such as a requirement to display their logo and to have that logo link to their site will be documented. If you are going to use an API read the T’s and C’s thoroughly before investing hours of development.

For more detailed coverage of API Basics see Stacy Mulcahy’s post here.

I recommend getting starter with your journey into the wonderful world of API’s at Mashery.com. Mashery is the premier API curator and provides a great set of services that aid developers in getting started using API’s such as Rotten Tomatoes, Edmunds, Active, Tom-Tom, Harper Collins and many more.

mashery_logo-small

The API Call Sequence Pattern

There is a common sequence pattern employed when working with web service API’s. You will find this pattern in all of the APIMASH Starter Kits regardless of implementation language and if you develop an app using web service API’s you will find yourself implementing this pattern as well. It is depicted in the diagram below. There are 4 steps  to this  sequence pattern:

  • Step 1: Invoke the web service API asynchronously
  • Step 2: Deserialize the payload into a Data Model
  • Step 3: Copy the Data Model to a View Model
  • Step 4: Bind the View Model to UI Controls

APICallSequence

Figure #1: The API Sequence Diagram

Since these API calls are being made over the Internet, we will need to make sure that our app never appears to pause or hang while we are waiting for the web service to respond. This loosely coupled approach to app design is very common in Windows and is the foundation for creating fast and fluid experiences for end users.

Step 1. The Asynchronous Call

We implement this loosely coupled model by writing the client side API invocations as asynchronous calls. On Windows we use the async and await keywords to decorate the API invocation so the UI thread is never blocked. The method is marked async which means that the method will contain an asynchronous call. The call to the GetStringAsync() method of the HttpClient object is decorated with the await keyword. The call will be handled on a background thread and when it returns the next line of code in the async method is executed, in this case the response payload string is returned.

async public string Invoke(string apiCall)
{
    var ws = new HttpClient();
    var uriAPICall = new Uri(apiCall);
    return await ws.GetStringAsync(uriAPICall);
}

Step 2. Deserializing the Payload

Well designed web service API’s return a rich set of nested data, sometimes referred to as a chunky response, to minimize the number of calls a client app needs to make to the remote API. API’s send back this chunky payload in either well-formed JSON or XML. Well-formed refers to that fact that the data should be in a form that can be described using a schema or class model and is easily deserialized by a common reusable function. If the data is not well-formed, the deserialization function will not be able to unwind the data into a usable object tree.

See an example of a JSON payload here

JSON which stands for Javascript Object Notation, is popular in that it is easily handled by Web applications written in Javascript. The object notation is immediately available to the calling application as a well formed object tree. If you are working in C#, then you will need to define a set of C# classes that mirror the structure of JSON or XML. At runtime, the string of JSON or XML is deserialized into memory using the classes that you define.

[DataContract]
    public class RottenTomatoesMovies
    {
        [DataMember(Name="total", IsRequired=false)]
        public int Total { get; set; }

        [DataMember(Name="movies")]
        public Movie[] Movies { get; set; }

        [DataMember(Name="links")]
        public SelfLinks SelfLinks { get; set; }

        [DataMember(Name="link_template")]
        public string LinkTemplate { get; set; }
    }

    [DataContract]
    public class Movie
    {
        [DataMember(Name="id")]
        public string Id { get; set; }

        [DataMember(Name="title")]
        public string Title { get; set; }

        [DataMember(Name="year")]
        public int Year { get; set; }

        [DataMember(Name="mpaa_rating")]
        public string MPAARating { get; set; }

As you can see from the abbreviated code snippet above, you define a set of classes that map to the JSON payload structure and decorate the classes using the [DataContract] and [DataMember] attributes. These attributes provide compile time directives and code generation rules for the deserialization function.

Note: Visual Studio Pro and above provide a ‘Paste Special’ feature that allows you to take JSON or XML and paste it into a class file to generate the matching class model. You will find this feature on the Edit Menu.

The Name parameter of the DataMember attribute gives you the chance to tell the compiler the name of the Javascript syntax that maps to the C# property. This way you can do a mapping between the Javascript notation and your C# property names if they do not match.

Now that you have defined the classes that will be used to deserialize the JSON or XML payload, you can take the string of JSON and pass it to the deserialization routine. Windows has a built in JSON and XML deserialization functions. They work very well. However for JSON there is also a very good third party library called JSON.NET. It provides richer error handling which is very useful during the development phase.

The code below demonstrates how to use JSON.NET. The method has been implemented to so that you can pass in the Type that you want to the payload to be deserialized into.

public static T DeserializeObject<T>(string objString)
{
    return (T)JsonConvert.DeserializeObject<T>(objString);
}

Step 3. Copy from the Data Model to the View-Model

Once you have deserialized the payload into a set of runtime objects, a.k.a. your Data Model, there is one more step before you display data to the user. You need to create your View Model. The View-Model, as defined by the architectural pattern Model VIew View-Model, is the subset of data that you want to display to the end user.

Since our API’s are likely returning more data then would be reasonable to display to the end user, we need to define that subset. In addition since we are using some form of markup language (XAML, HTML5) to display the information, a specialized object model that understands control binding must be used.

In C# we deriving our View Model classes from the INotifyPropertyChanged interface and implementing the OnPropertyChanged() method of that interface. This method provides a communication interface between the CUI Control and the View Model so that when the View Model changes, the UI knows to update and when the end user updates the data on the screen, the View Model is notified of the update.

Finally we implement a Copy() method on our top level View Model class so that we can pass in the Data Model and copy just the data to be displayed to the user.

The code below is from the Rotten Tomatoes API Starter Kit. It is a smaple of the View Model implementation that shows how a View Model for Movie Reviews is implemented.

    

public class APIMASH_OM_Bindable : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null)
    {
        if (object.Equals(storage, value)) return false;
        storage = value;
        this.OnPropertyChanged(propertyName);
        return true;
    }

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var eventHandler = this.PropertyChanged;
        if (eventHandler != null)
        {
            eventHandler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

public class MovieReviewItem : APIMASH_OM_Bindable
{
    public MovieReviewItem(
        string critic, 
        string date, 
        string freshness, 
        string publication, 
        string quote,
        string link)
    {
        this._critic = critic;
        this._date = date;
        this._freshness = freshness;
        this._publication = publication;
        this._quote = quote;
        this._link = link;
    }

    private string _critic = string.Empty;
    public string Critic
    {
        get { return this._critic; }
        set { this.SetProperty(ref this._critic, value); }
    }

    private string _date = string.Empty;
    public string Date
    {
        get { return this._date; }
        set { this.SetProperty(ref this._date, value); }
    }

    private string _freshness = string.Empty;
    public string Freshness
    {
        get { return this._freshness; }
        set { this.SetProperty(ref this._freshness, value); }
    }

    private string _publication = string.Empty;
    public string Publication
    {
        get { return this._publication; }
        set { this.SetProperty(ref this._publication, value); }
    }

    private string _quote = string.Empty;
    public string Quote
    {
        get { return this._quote; }
        set { this.SetProperty(ref this._quote, value); }
    }

    private string _link = string.Empty;
    public string Link
    {
        get { return this._link; }
        set { this.SetProperty(ref this._link, value); }
    }
}

public class MovieReviewGroup
{
    private ObservableCollection<MovieReviewItem> _items;

    public MovieReviewGroup()
    {
        _items = new ObservableCollection<MovieReviewItem>();
    }

    public ObservableCollection<MovieReviewItem> Items
    {
        get { return this._items; }
    }

    public void Copy(MovieReviews movieReviews)
    {
        foreach (var mi in movieReviews.Reviews.Select(r => new MovieReviewItem(
                r.Critic,
                r.Date,
                r.Freshness,
                r.Publication,
                r.Quote,
                r.Link.Review)))
        {
            this._items.Add(mi);
        }
    }
}

Step 4. Bind to WinRT Controls

Data Binding is a multi-article topic all to itself so I won’t try to recreate that content here. For a detailed walkthrough on Data Binding in C#, C++ and VB, I recommend these 3 articles:

If you are working in HTML5/Javascript, I recommend these 3 articles:

Summary

So lets recap…we made our asynchronous call and deserialized the payload into our Data Model and copied a subset of that data into our View Model. Finally we bound our View Model to UI Controls.

Now its your turn.

Download the APIMASH Starter Kits and give them a spin. The README files for each will provide details on how to get your Developer Key and begin customizing the kits to create your own app.

Check out these article for details on individual APIMASH Starter Kits:

Stay tuned for more!! -bob

 

6 thoughts on “APIMASH: Using API’s to create compelling Windows Apps

Leave a Reply

Your email address will not be published. Required fields are marked *