This post is about using Retrofit to consume HTTP based APIs.
Retrofit is a great and popular API client library for Java (and by extension also for Android) developed by Square. Here’s a few links to start things off:
- square.github.io/retrofit - original source
- Retrofit Javadoc
- inthecheesefactory.com/blog/retrofit-2.0
- github.com/metachris/retrofit2-samples - IntelliJ project for this blog post
Retrofit makes it easy to develop API clients by describing API endpoints and the results like this:
classProfile{Stringusername;Stringemail;}...@GET("/profile")Call<Profile>getProfile();
A great endpoint to test API calls is httpbin.org, a website/api which returns various information about the request and more.
Getting Started
First of all we need to include the Retrofit library in a project. Using gradle this is
accomplished by adding the following dependencies to build.gradle
:
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
The first dependency includes Retrofit itself, the second dependency includes the GSON library for (de-)serialization of JSON objects.
The Code
This is the sample code for a number of httpbin.org api requests:
1importretrofit.Call; 2importretrofit.Callback; 3importretrofit.GsonConverterFactory; 4importretrofit.Response; 5importretrofit.Retrofit; 6importretrofit.http.*; 7 8importjava.io.IOException; 9importjava.util.Map; 10 11publicclassHttpApi{ 12 13publicstaticfinalStringAPI_URL="http://httpbin.org"; 14 15/** 16 * Generic HttpBin.org Response Container 17 */ 18staticclassHttpBinResponse{ 19// the request url 20Stringurl; 21 22// the requester ip 23Stringorigin; 24 25// all headers that have been sent 26Mapheaders; 27 28// url arguments 29Mapargs; 30 31// post form parameters 32Mapform; 33 34// post body json 35Mapjson; 36} 37 38/** 39 * Exemplary login data sent as JSON 40 */ 41staticclassLoginData{ 42Stringusername; 43Stringpassword; 44 45publicLoginData(Stringusername,Stringpassword){ 46this.username=username; 47this.password=password; 48} 49} 50 51/** 52 * HttpBin.org service definition 53 */ 54publicinterfaceHttpBinService{ 55@GET("/get") 56Call<HttpBinResponse>get(); 57 58// request /get?testArg=... 59@GET("/get") 60Call<HttpBinResponse>getWithArg( 61@Query("testArg")Stringarg 62); 63 64// POST form encoded with form field params 65@FormUrlEncoded 66@POST("/post") 67Call<HttpBinResponse>postWithFormParams( 68@Field("field1")Stringfield1 69); 70 71// POST form encoded with form field params 72@POST("/post") 73Call<HttpBinResponse>postWithJson( 74@BodyLoginDataloginData 75); 76} 77 78publicstaticvoidtestApiRequest(){ 79// Retrofit setup 80Retrofitretrofit=newRetrofit.Builder() 81.baseUrl(API_URL) 82.addConverterFactory(GsonConverterFactory.create()) 83.build(); 84 85// Service setup 86HttpBinServiceservice=retrofit.create(HttpBinService.class); 87 88// Prepare the HTTP request 89Call<HttpBinResponse>call=service.postWithJson(newLoginData("username","secret")); 90 91// Asynchronously execute HTTP request 92call.enqueue(newCallback<HttpBinResponse>(){ 93/** 94 * onResponse is called when any kind of response has been received. 95 */ 96@Override 97publicvoidonResponse(Response<HttpBinResponse>response,Retrofitretrofit){ 98// http response status code + headers 99System.out.println("Response status code: "+response.code());100101// isSuccess is true if response code => 200 and <= 300102if(!response.isSuccess()){103// print response body if unsuccessful104try{105System.out.println(response.errorBody().string());106}catch(IOExceptione){107// do nothing108}109return;110}111112// if parsing the JSON body failed, `response.body()` returns null113HttpBinResponsedecodedResponse=response.body();114if(decodedResponse==null)return;115116// at this point the JSON body has been successfully parsed117System.out.println("Response (contains request infos):");118System.out.println("- url: "+decodedResponse.url);119System.out.println("- ip: "+decodedResponse.origin);120System.out.println("- headers: "+decodedResponse.headers);121System.out.println("- args: "+decodedResponse.args);122System.out.println("- form params: "+decodedResponse.form);123System.out.println("- json params: "+decodedResponse.json);124}125126/**127 * onFailure gets called when the HTTP request didn't get through.128 * For instance if the URL is invalid / host not reachable129 */130@Override131publicvoidonFailure(Throwablet){132System.out.println("onFailure");133System.out.println(t.getMessage());134}135});136}137}
You can find a IntelliJ project with the full source code on github.com/metachris/retrofit2-samples.
Feedback, suggestions and pull requests are welcome!