This is the first tutorial in an extensive series on Retrofit. The series dives through all aspects of Retrofit and prepares you for many potential use cases. You’ll get to know Retrofit’s range of functions and extensibility.
Retrofit Series Overview
- Getting Started and Creating an Android Client
- Basics of API Description
- Creating a Sustainable Android Client
- URL Handling, Resolution and Parsing
- How to Change API Base Url at Runtime
- Multiple Server Environments (Develop, Staging, Production)
- Share OkHttp Client and Converters between Retrofit Instances
- Upgrade Guide from 1.9
- Beyond Android: Retrofit for Java Projects
- How to use OkHttp 3 with Retrofit 1
- Synchronous and Asynchronous Requests
- Send Objects in Request Body
- Add Custom Request Header
- Manage Request Headers in OkHttp Interceptor
- Dynamic Request Headers with @HeaderMap
- Multiple Query Parameters of Same Name
- Optional Query Parameters
- Send Data Form-Urlencoded
- Send Data Form-Urlencoded Using FieldMap
- How to Add Query Parameters to Every Request
- Add Multiple Query Parameter With QueryMap
- How to Use Dynamic Urls for Requests
- Constant, Default and Logic Values for POST and PUT Requests
- Cancel Requests
- Reuse and Analyze Requests
- Optional Path Parameters
- How to Send Plain Text Request Body
- Customize Network Timeouts
- How to Trust Unsafe SSL certificates (Self-signed, Expired)
- Dynamic Endpoint-Dependent Interceptor Actions
- How to Update Objects on the Server (PUT vs. PATCH)
- How to Delete Objects on the Server
- Introduction to (Multiple) Converters
- Adding & Customizing the Gson Converter
- Implementing Custom Converters
- How to Integrate XML Converter
- Access Mapped Objects and Raw Response Payload
- Supporting JSON and XML Responses Concurrently
- Handling of Empty Server Responses with Custom Converter
- Send JSON Requests and Receive XML Responses (or vice versa)
- Unwrapping Envelope Responses with Custom Converter
- Wrapping Requests in Envelope with Custom Converter
- Define a Custom Response Converter
Within this first tutorial we’re going through the basics of Retrofit and create an Android client for HTTP requests against the GitHub API.
What is Retrofit
The official page describes Retrofit as
A type-safe REST client for Android and Java.
You’ll use annotations to describe HTTP requests, URL parameter replacement and query parameter support is integrated by default. Additionally, it provides functionality for custom headers, multipart request body, file uploads and downloads, mocking responses and much more. In later tutorials we’ll look at all of these in more detail.
Prepare Your Android Project
Let’s get our hands dirty and back to the keyboard. If you already created your Android project, just go ahead and start from the next section. Otherwise, create a new project in your favorite IDE. We prefer Android Studio with Gradle as the build system, but you surely can use your IDE of choice or Maven as well.
Define Dependencies: Gradle or Maven
At first, set Retrofit as a dependency for your project. Select your used build system and define Retrofit and its dependencies in your build.gradle
or pom.xml
. When running the command to build your code, the build system will download and provide the library for your project.
Retrofit 2
Our recommendation Retrofit 2 leverages OkHttp as the networking layer by default and is built on top of it. You don’t need to explicitly define OkHttp as a dependency for your project, unless you have a specific version requirement. However, Retrofit 2 requires a dependency for the automatic conversion of request and response payloads. Use the following dependencies if you’re using Retrofit in version 2 and want to map JSON payloads with GSON:
build.gradle
dependencies {
// Retrofit & OkHttp
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
}
pom.xml
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>converter-gson</artifactId>
<version>2.5.0</version>
</dependency>
Retrofit 1.9
If you still rely on Retrofit 1.9, you need to declare it with OkHttp, since it functions as network layer for Retrofit.
build.gradle
dependencies {
// Retrofit & OkHttp
implementation 'com.squareup.retrofit:retrofit:1.9.0'
implementation 'com.squareup.okhttp:okhttp:2.7.2'
}
pom.xml
<dependency>
<groupId>com.squareup.retrofit</groupId>
<artifactId>retrofit</artifactId>
<version>1.9.0</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp</groupId>
<artifactId>okhttp</artifactId>
<version>2.7.2</version>
</dependency>
Android’s Network Permission
Retrofit performs HTTP requests against an API running on a server somewhere in the Internet. Executing those requests from an Android application requires the Internet permission to open network sockets. You need to define the permission within the AndroidManifest.xml
file. If you didn’t set the Internet permission yet, please add the following line within your AndroidManifest.xml
definition:
<uses-permission android:name="android.permission.INTERNET" />
Now that your project is ready to integrate Retrofit, let’s create an Android API/HTTP client.
How to Describe API Endpoints
Before you can start with your first requests, you need to describe the API endpoints you want to interact with. In this tutorial we’ll just describe a simple GitHub endpoint. We'll go into more detail on API endpoint description in a later tutorial.
First, you have to create an interface and define required methods.
GitHub Client
The following code defines the GitHubClient
and a method reposForUser
to request the list of repositories for a given user. The @GET
annotation declares that this request uses the HTTP GET
method. The code snippet also illustrates the usage of Retrofit’s path parameter replacement functionality. In the defined method the {user}
path will be replaced with the given variable values when calling the reposForUser
method.
Retrofit 2
public interface GitHubClient {
@GET("/users/{user}/repos")
Call<List<GitHubRepo>> reposForUser(
@Path("user") String user
);
}
Retrofit 1.9
public interface GitHubClient {
@GET("/users/{user}/repos")
void reposForUser(
@Path("user") String user,
Callback<List<GitHubRepo>> callback
);
}
There is a defined class GitHubRepo
. This class comprises required class properties to map the response data.
public class GitHubRepo {
private int id;
private String name;
public GitHubRepo() {
}
public int getId() {
return id;
}
public String getName() {
return name;
}
}
With regard to the previously mentioned JSON mapping: the GitHubClient
interface defines a method named reposForUser
with return type List<GitHubRepo>
. Retrofit makes sure the server response gets mapped correctly (in case the response matches the given class).
Retrofit REST Client
After describing the API interface and the object model, it’s time to prepare an actual request. Retrofit’s basis for all requests is the RestAdapter
(v1.9) or Retrofit
(2.0+) class. In both versions you create and configure them with a fluent API. To that end, you can use the builder to set some general options for all requests, i.e. the base URL or the converter. We’ll go into more detail for all of the available options in a later tutorial.
Once you’ve created an adapter, you’re able to create a client
. You’ll use the client
to execute the actual requests.
Retrofit 2
String API_BASE_URL = "https://api.github.com/";
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(
GsonConverterFactory.create()
);
Retrofit retrofit =
builder
.client(
httpClient.build()
)
.build();
GitHubClient client = retrofit.create(GitHubClient.class);
Retrofit 1.9
String API_BASE_URL = "http://your.api-base.url";
RestAdapter.Builder builder =
new RestAdapter.Builder()
.setEndpoint(API_BASE_URL)
.setClient(
new OkClient(new OkHttpClient())
);
RestAdapter adapter = builder.build();
GitHubClient client = adapter.create(GitHubClient.class);
In our example, GitHub’s API base URL is https://api.github.com/
. In the code snippets above we just went with the minimum options. There are a lot more options for fine-tuned control over your requests. But it’s sufficient for the purpose of making our first request!
JSON Mapping
In most cases requests to a server, and the responses from the server, are not Java objects. They’re mapped to some language neutral format like JSON. Since GitHub’s API uses JSON, we need to prepare Retrofit for it.
Retrofit 1.9 ships with Google’s Gson (which parses JSON to and from Java objects) by default. All you need to do is define the class of your response object and the response will be mapped automatically.
When using Retrofit 2, you need to add a converter explicitly to the Retrofit
object. Above, we’ve added the following line in our build.gradle
file to import the Gson converter for Retrofit 2.
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
If you followed our tutorial from the beginning, you’ve already done this!
Nevertheless, in a future tutorial, we’ll look at converters for other data formats so you can also interact with XML or Protobuf APIs.
Retrofit in Use
After doing a ton of prep work, it’s time to reap the benefits and finally make your request. The good news: it’s only going to be a few lines!
The first line of creating a client
object should already be familiar. The way of actually executing the request depends on the Retrofit version.
Retrofit 1.9
For Retrofit 1.9, you’re passing a callback as the last parameter. The callback gets executed as soon as Retrofit has fulfilled the request, got a response and parsed it. There is also a simpler way by using synchronous request, but those are not usable in most Android use cases.
// Create a very simple REST adapter which points the GitHub API endpoint.
GitHubClient client = adapter.create(GitHubClient.class);
// Fetch a list of the Github repositories.
client.reposForUser("fs-opensource", new Callback<List<GitHubRepo>>() {
@Override
public void success(List<GitHubRepo> repos, Response response) {
// The network call was a success and we got a response
// TODO: use the repository list and display it
}
@Override
public void failure(RetrofitError error) {
// the network call was a failure or the server send an error
// TODO: handle error
}
});
Retrofit 2
In Retrofit 2, you also use your client
object. However, here you don’t pass your callback as the last parameter. You use the client
to get a call
object. Once you’ve invoked .enqueue
on the created call
object the request will be made by Retrofit. There is also an option to do a synchronous request, but we’ll look at those later.
// Create a very simple REST adapter which points the GitHub API endpoint.
GitHubClient client = retrofit.create(GitHubClient.class);
// Fetch a list of the Github repositories.
Call<List<GitHubRepo>> call =
client.reposForUser("fs-opensource");
// Execute the call asynchronously. Get a positive or negative callback.
call.enqueue(new Callback<List<GitHubRepo>>() {
@Override
public void onResponse(Call<List<GitHubRepo>> call, Response<List<GitHubRepo>> response) {
// The network call was a success and we got a response
// TODO: use the repository list and display it
}
@Override
public void onFailure(Call<List<GitHubRepo>> call, Throwable t) {
// the network call was a failure
// TODO: handle error
}
});
In either case, you should be able to make your very first request with Retrofit. If everything went well, Retrofit will return you a handy List<GitHubRepo>
, which you can further use to display the data in your app.
Initially, Retrofit looks pretty complex. We promise, it’s very clean and pays off if you’re working on a larger project. If you spend a little more time reading a few more tutorials, you’ll soon also love Retrofit.
What Comes Next
In this tutorial, you’ve learned the basics of Retrofit. In multiple sections, we’ve only given you the code without many explanations. We highly recommend reading up on those parts in more detail. You should start by reading how to describe API endpoints with Retrofit.
If you've feedback or a question, let us know in the comments or on Twitter @futurestud_io.
Enjoy coding & make it rock!