Retrofit is a type-safe rest client for java/android that one can use for easily consuming rest services. It supports both synchronous and asynchronous retrieval. In this post, I will explain an example which shows how you can integrate it with your android application for consuming rest services asynchronously. The example will show its integration for doing feed search with Feedly. Feedly’s basic feed search is free, you can find the document here Feedly Search Service.
Setting up Retrofit : -
I am now using android studio instead of eclipse as android studio is based on IntelliJ Idea platform and performs much better in every aspect. In your build add the following Gradle dependency, rest will be managed by Gradle.
compile 'com.squareup.retrofit:retrofit:1.6.1'
About Feedly’s feed search API :-
Feedly's search feed API has the following request signature. GET /v3/search/feeds It accepts the following three parameters: query Required string search query. Can be a feed url, a site title, a site url or a #topic count Optional number number of results. default value is 20 locale Optional locale hint the search engine to return feeds in that locale (e.g. “pt”, “fr_FR”).
A sample request response is shown below:-
Request:
GET feedly.com/v3/search/feeds?query=ramannanda.blogspot.com
Response:
{"queryType":"term","results":[{"deliciousTags":["adf"],"feedId":"feed/http://ramannanda.blogspot.com/feeds/posts/default","language":"en","subscribers":23,"title":"Technical Essentials","velocity":0.0,"lastUpdated":1402601340000,"website":"http://ramannanda.blogspot.com/","score":2.299999952316284,"estimatedEngagement":5,"description":"Java, ADF, Identity Management, Fusion Middleware, Linux, Counter Strike 1.6, BSD, Windows, \nProgramming, Search Engines","scheme":"TEXT:BASELINE:ORGANIC_SEARCH","contentType":"longform","partial":false,"twitterScreenName":"ramannanda9","twitterFollowers":75,"facebookUsername":"technicalessentials9911","facebookLikes":3,"iconUrl":"http://storage.googleapis.com/site-assets/WkQvKWtcgur8yMCOJbBWti9mkZPUEZGutfEwCkYH6Pc_icon-1484cef868f","visualUrl":"http://storage.googleapis.com/site-assets/WkQvKWtcgur8yMCOJbBWti9mkZPUEZGutfEwCkYH6Pc_visual","coverUrl":"http://storage.googleapis.com/site-assets/WkQvKWtcgur8yMCOJbBWti9mkZPUEZGutfEwCkYH6Pc_cover","coverColor":"C0DEED"}],"related":["adf"],"scheme":"subs.0"}
Using Retrofit:
Now we need to setup the service interface which can be used to call this service and implement a callback to which the results will be assigned.
Search Interface:
public interface FeedlySuggestionsService {
@GET("/v3/search/feeds")
void searchFeeds(@QueryMap Map<String, String> options, Callback<FeedlyResponse> cb);
}
The interface is pretty easy to understand.
- It targets search feeds service as explained above.
- The searchFeeds method accepts a map of key-value request parameters.
- It also specifies a parameter that is of callback interface, which we need to implement in an activity or fragment to use the results.
- Notice that FeedlyResponse is a custom class and retrofit will parse the JSON and populate the results. Pretty neat!
The POJO classes for response are mentioned below:
The FeedlyResponse class:-
public class FeedlyResponse {
public FeedlyResponse(){
}
public List<FeedlyResult> getResults() {
return results;
}
public void setResults(List<FeedlyResult> results) {
this.results = results;
}
private List<FeedlyResult> results;
}
The FeedlyResult class.
public class FeedlyResult {
private String feedId;
private String title;
private String coverUrl;
private String visualUrl;
private String iconUrl;
public String getSubscribers() {
return subscribers;
}
public void setSubscribers(String subscribers) {
this.subscribers = subscribers;
}
private String subscribers;
public String getFeedId() {
return feedId;
}
public void setFeedId(String feedId) {
this.feedId = feedId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getCoverUrl() {
return coverUrl;
}
public void setCoverUrl(String coverUrl) {
this.coverUrl = coverUrl;
}
public String getVisualUrl() {
return visualUrl;
}
public void setVisualUrl(String visualUrl) {
this.visualUrl = visualUrl;
}
public String getIconUrl() {
return iconUrl;
}
public void setIconUrl(String iconUrl) {
this.iconUrl = iconUrl;
}
}
If you see the JSON response, you will see that FeedlyResponse class maps to the response object that is returned and List<FeedlyResult> object maps to the results array. As you can see this is pretty cool, because retrofit will populate only the parameters that you specify.
In your activity/fragment:-
You just need to implement a method which fetches the data as shown below.
private void loadData(String searchText) {
//specify endpoint and build the restadapter instance
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("http://feedly.com")
.build();
//Now use restadapter to create an instance of your interface
FeedlySuggestionsService searchService=restAdapter.create(FeedlySuggestionsService.class);
//populate the request parameters
HashMap queryMap=new HashMap();
queryMap.put("query",searchText);
//implement the Callback<T> interface for retrieving the response
searchService.searchFeeds(queryMap, new Callback<FeedlyResponse>() {
@Override
public void success(FeedlyResponse feedlyResponse, Response response) {
//convert list to cursor. more on this later
MatrixCursor matrixCursor= convertToCursor(feedlyResponse.getResults());
mSearchViewAdapter.changeCursor(matrixCursor);
}
@Override
public void failure(RetrofitError error) {
Log.e(tag, error.toString());
}
});
}
I think the comments on the method should suffice, but let me explain what’s happening in the above method.
- First, we are using the builder pattern to build the RestAdapter. Here, we are specifying the endpoint to use.
- We use the restadapter to create an instance for the interface we had created.
- Implement the callback interface’s success and failure methods.
Notice that we did not have to parse the JSON to map the parameters to our POJO class, it was done automatically and asynchronous capability was added just by declaration of the callback parameter.
Have fun and let me have some REST!