In my last post we went over OAuth in general and we looked at how to use a Java library called Leeloo to authenticate with a service providing an OAuth 2 implementation.
Now that we are able to authenticate a service with OAuth, we need to be able to actually use that service to do something useful.
Many popular web service APIs like Facebook and Twitter provide a REST based implementation.
In this post I’ll show you how to easily connect to one of these web services from Android and parse any responses you get back.
Should I use a REST library?
This is a valid question we should address before getting into the details.
My answer to this question is basically “no.”
I first tried the approach of using a REST library to make it easier to communicate to a REST based web service, but quickly found the overhead of the library was more than the benefit it provided.
If you come from a background of calling XML and SOAP based web services, you might be surprised by this answer. With SOAP based web services it was a huge benefit to use a library to generate a proxy for you to call the web service and let you not have to worry about parsing XML and SOAP headers.
With REST it is completely different. The whole point of moving to REST based web services is to simplify the process of calling web services.
Most REST based web service interfaces are extremely simple to use. The idea is that the URL itself contains as much of the data as possible and additional data is included in the POST body.
By adding the complexity of learning a REST library and implementing the proper interfaces required to make it work seamlessly, we can easily add more complexity and overhead than just creating a HTTP request ourselves and parsing the responses.
For this approach I am going to show you how to do just that.
Calling the REST service
In order to call a REST service in Android we are going to first have to discover and understand the REST API provided to us, then make the appropriate calls with the OAuth token we got from authenticating. Finally, we will parse the result of the call and get back our response.
Discovering the API
Because REST is not really a standard, but rather an ideal, there is not a standard way REST APIs are implemented.
You’ll have to take a look at the documentation for the REST API you want to call to figure out exactly what a call should look like.
In general though a REST API will involve making some kind of HTTP GET, POST, PUT or DELETE request and passing data through the URL or in the request body.
Here is an example of the Dailymile.com API which I have been recently integrating my app to use.
You can see the full API documentation here.
For this API, I am going to show you how I am creating a workout entry using a post.
Making the REST call
In order to make a REST call in Android, we are going to use a HttpClient object and the appropriate http request class.
In this example we are going to use the JSONObject class to create some data in JSON format that we can pass to the REST call by embedding it in the post.
I looked at the API for posting a workout entry to Dailymile, and the format of the request should look like this:
The API also indicates that it expects the post body to contain some JSON and gives us a list of required and optional entries that need to be in that JSON object.
Let’s take a look at how I am making this call and then we’ll break it down some.
HttpClient httpClient = new DefaultHttpClient(); HttpPost httpPost = new HttpPost( "https://api.dailymile.com/entries.json?oauth_token=" + token); httpPost.setHeader("content-type", "application/json"); JSONObject data = new JSONObject(); data.put("message", dailyMilePost.getMessage()); JSONObject workoutData = new JSONObject(); data.put("workout", workoutData); workoutData.put("activity_type", dailyMilePost.getActivityType()); workoutData.put("completed_at", dailyMilePost.getCompletedAt()); JSONObject distanceData = new JSONObject(); workoutData.put("distance", distanceData); distanceData.put("value", dailyMilePost.getDistanceValue()); distanceData.put("units", dailyMilePost.getDistanceUnits()); workoutData.put("duration", dailyMilePost.getDurationInSeconds()); workoutData.put("title", dailyMilePost.getTitle()); workoutData.put("felt", dailyMilePost.getFelt()); StringEntity entity = new StringEntity(data.toString()); httpPost.setEntity(entity); HttpResponse response = httpClient.execute(httpPost);
You can see that I am first creating an HttpClient object and an HttpPost object. The HttpPost has its URL set to the URL for the API call and I am adding a query string parameter to provide the OAuth token we got when when authenticated in my previous post.
I set the content type to be JSON so that we can get back a JSON object from the API call and so it knows that we are passing JSON data.
Then I construct a JSON object in the format specified by the API. The way to construct the JSON object is to basically create a set of keys and values that are specified by the API you are calling. In this instance I have a “message” key which I put the message data into.
The only tricky part is that JSON objects can be nested. So if you look at the key “workout” in the example above, I am creating a brand new JSON object to use as the value for that key which has its own subkeys which could contain more JSON objects.
Doing it this way is much more simple than trying to construct the string yourself. The string we end up constructing will look something like this:
Finally, I put the JSON data into a StringEntity class and set it as the entity on the HTTP Post. Then we can call execute on the HttpClient to execute the HTTP POST.
Handling the response
HttpResponse response = httpClient.execute(httpPost); String responseString = EntityUtils.toString(response.getEntity()); JSONObject responseJSON = new JSONObject(responseString); int workoutId = responseJSON.getInt("id");
All we are doing in this case is getting the response from the execute call on the HttpClient object, then using EntityUtils.toString to convert the response’s entity to a string representation. Finally, we construct a new JSONObject from that string.
We can then easily extract any data out of the JSON object by using the methods on that JSON object that let us get typed values out of it. For this example, I know that I am getting back some JSON that has a key “id” which is the id of the workout I created with my POST.
It is really that simple
The example I am showing you here is one of the more complex examples of calling a REST based API, because we are having to POST and parse JSON data.
In many API calls, you can just use an HTTP GET or a POST without any data to accomplish what you need to in the API.
Some REST based APIs will allow or require data to be passed in a different format, but most of them use JSON notation, which I find the easiest to work with.
Hopefully with these series of posts you can now authenticate against an OAuth 2 based service and make calls to the API to get and manipulate data in Android.
If you have any questions, feel free to drop me a line or post in the comments below.