How to make POST, GET, PUT and DELETE requests with Retrofit using Kotlin

Retrofit is the most popular HTTP library and one of the most popular 3rd party libraries on Android.

Today, I’ll to show you how to do the following HTTP requests using Retrofit:

Retrofit not only can make HTTP requests but can also parse the JSON simultaneously.

I’m NOT going to show you how to parse the JSON data in this tutorial, but only how to make HTTP requests and print the results.

If you want to parse JSON with Retrofit, you need to read the current article first and then follow this.

Adding the libraries

Go to your app-level build.gradle file and add the following dependencies:

// ... dependencies { // ... // Coroutines to make the HTTP requests asynchronous(In the background thread) implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9' // Retrofit implementation 'com.squareup.retrofit2:retrofit:2.9.0' // Okhttp3 for the POST requests implementation 'com.squareup.okhttp3:okhttp:4.9.0' // Gson (To convert raw JSON to pretty JSON) implementation 'com.google.code.gson:gson:2.8.6' // ... }
Code language: Kotlin (kotlin)

at the same file, at the bottom of the android section, add:

android { // ... compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }
Code language: Swift (swift)

Adding Permissions & Preparing the Files

Go to the AndroidManifest.xml file and add the following permission:

<uses-permission android:name="android.permission.INTERNET" />
Code language: HTML, XML (xml)

Now, create a new Kotlin Interface file to put our @POST, @GET, @PUT, and @DELETE annotations later.

Right-click on your project name > New > Kotlin File/Class

Select Interface, name the file APIService and press Enter

After that, the file will look like this:

Adding data using POST method

To add data to the server, you need to use the HTTP request method POST.

Before you upload the data, you have to define what type of data you are uploading (e.g., raw JSON, media e.t.c). To do that, you need to set the MIME type.

  • application/json for raw JSON data
  • multipart/form-data for files, like images, pdfs, texts e.t.c
  • application/x-www-form-urlencoded for passing the paramers encoded in the URL

• Uploading JSON data (application/json)

In this example, we’re going to POST the following data as raw JSON data in the URL: http://dummy.restapiexample.com/api/v1/create

  • name: Jack
  • salary: 3540
  • age: 23

First, in the APIService.kt file add the following @POST annotation:

interface APIService { // ... @POST("/api/v1/create") suspend fun createEmployee(@Body requestBody: RequestBody): Response<ResponseBody> // ... }
Code language: Kotlin (kotlin)

Then, to create the JSON we’ll use the JSONObject() class and add the data we want to upload.

So, at the end, the POST request will look like this:

fun rawJSON() { // Create Retrofit val retrofit = Retrofit.Builder() .baseUrl("http://dummy.restapiexample.com") .build() // Create Service val service = retrofit.create(APIService::class.java) // Create JSON using JSONObject val jsonObject = JSONObject() jsonObject.put("name", "Jack") jsonObject.put("salary", "3540") jsonObject.put("age", "23") // Convert JSONObject to String val jsonObjectString = jsonObject.toString() // Create RequestBody ( We're not using any converter, like GsonConverter, MoshiConverter e.t.c, that's why we use RequestBody ) val requestBody = jsonObjectString.toRequestBody("application/json".toMediaTypeOrNull()) CoroutineScope(Dispatchers.IO).launch { // Do the POST request and get response val response = service.createEmployee(requestBody) withContext(Dispatchers.Main) { if (response.isSuccessful) { // Convert raw JSON to pretty JSON using GSON library val gson = GsonBuilder().setPrettyPrinting().create() val prettyJson = gson.toJson( JsonParser.parseString( response.body() ?.string() // About this thread blocking annotation : https://github.com/square/retrofit/issues/3255 ) ) Log.d("Pretty Printed JSON :", prettyJson) } else { Log.e("RETROFIT_ERROR", response.code().toString()) } } } }
Code language: Kotlin (kotlin)

• Uploading Files (multipart/form-data)

In this example, we’re going to POST a String value and a .txt file in the URL: https://httpbin.org/post

  • email: jack@email.com
  • file: lorem_ipsum.txt

First, in the APIService.kt file add:

interface APIService { // ... @Multipart @POST("/post") suspend fun uploadEmployeeData(@PartMap map: HashMap<String?, RequestBody?>): Response<ResponseBody> // ... }
Code language: Kotlin (kotlin)

As you see, we’re using HashMap to add the data (string and .txt file), alongside with Retrofit’s @PartMap annotation

…and the POST request will be:

fun formData() { // Create Retrofit val retrofit = Retrofit.Builder() .baseUrl("https://httpbin.org") .build() // Create Service val service = retrofit.create(APIService::class.java) // List of all MIME Types you can upload: https://www.freeformatter.com/mime-types-list.html // Get file from assets folder val file = getFileFromAssets(this, "lorem_ipsum.txt") val fields: HashMap<String?, RequestBody?> = HashMap() fields["email"] = ("jack@email.com").toRequestBody("text/plain".toMediaTypeOrNull()) fields["file\"; filename=\"upload_file.txt\" "] = (file).asRequestBody("text/plain".toMediaTypeOrNull()) CoroutineScope(Dispatchers.IO).launch { // Do the POST request and get response val response = service.uploadEmployeeData(fields) withContext(Dispatchers.Main) { if (response.isSuccessful) { // Convert raw JSON to pretty JSON using GSON library val gson = GsonBuilder().setPrettyPrinting().create() val prettyJson = gson.toJson( JsonParser.parseString( response.body() ?.string() // About this thread blocking annotation : https://github.com/square/retrofit/issues/3255 ) ) Log.d("Pretty Printed JSON :", prettyJson) } else { Log.e("RETROFIT_ERROR", response.code().toString()) } } } }
Code language: Kotlin (kotlin)

• Uploading with parameters encoded in the URL (application/x-www-form-urlencoded)

To have the parameters encoded in the URL, all you have to do is to add the @FormUrlEncoded annotation in the APIService.kt file and use HashMap with the @FieldMap annotation.

interface APIService { // ... @FormUrlEncoded @POST("/post") suspended fun createEmployee(@FieldMap params: HashMap<String?, String?>): Response<ResponseBody> // ... }
Code language: Kotlin (kotlin)

And when you make the POST request, create a HashMap and add the parameters you want:

fun urlEncoded() { // Create Retrofit val retrofit = Retrofit.Builder() .baseUrl("https://postman-echo.com") .build() // Create Service val service = retrofit.create(APIService::class.java) // Create HashMap with fields val params = HashMap<String?, String?>() params["name"] = "Jack" params["salary"] = "8054" params["age"] = "45" CoroutineScope(Dispatchers.IO).launch { // Do the POST request and get response val response = service.createEmployee(params) withContext(Dispatchers.Main) { if (response.isSuccessful) { // Convert raw JSON to pretty JSON using GSON library val gson = GsonBuilder().setPrettyPrinting().create() val prettyJson = gson.toJson( JsonParser.parseString( response.body() ?.string() // About this thread blocking annotation : https://github.com/square/retrofit/issues/3255 ) ) Log.d("Pretty Printed JSON :", prettyJson) } else { Log.e("RETROFIT_ERROR", response.code().toString()) } } } }
Code language: Kotlin (kotlin)

Retrieving data using GET method

To retrieve the data from the server, you need to use the HTTP request method GET.

In this example, we’re going to get a list of employees from the URL: http://dummy.restapiexample.com/api/v1/employees

Go to the APIService.kt file, add the @GET annotation with the path of the URL:

interface APIService { // ... @GET("/api/v1/employees") suspend fun getEmployees(): Response<ResponseBody> // ... }
Code language: Kotlin (kotlin)

And make the GET request:

fun getMethod() { // Create Retrofit val retrofit = Retrofit.Builder() .baseUrl("http://dummy.restapiexample.com") .build() // Create Service val service = retrofit.create(APIService::class.java) CoroutineScope(Dispatchers.IO).launch { /* * For @Query: You need to replace the following line with val response = service.getEmployees(2) * For @Path: You need to replace the following line with val response = service.getEmployee(53) */ // Do the GET request and get response val response = service.getEmployees() withContext(Dispatchers.Main) { if (response.isSuccessful) { // Convert raw JSON to pretty JSON using GSON library val gson = GsonBuilder().setPrettyPrinting().create() val prettyJson = gson.toJson( JsonParser.parseString( response.body() ?.string() // About this thread blocking annotation : https://github.com/square/retrofit/issues/3255 ) ) Log.d("Pretty Printed JSON :", prettyJson) } else { Log.e("RETROFIT_ERROR", response.code().toString()) } } } }
Code language: Kotlin (kotlin)

Using @Path and @Query

@Path

If you want to get the data of a specific user using their id, you can do it by using the @Path annotation:

interface APIService { // ... // Request using @Path (e.g https://reqres.in/api/user/53 - This URL is just an example, it's not working) @GET("/api/users/{Id}") suspend fun getEmployee(@Path("Id") employeeId: String): Response<ResponseBody> // ... }
Code language: Kotlin (kotlin)

Then, in your GET request, you can set the user id like that:

val response = service.getEmployee("53")
Code language: Kotlin (kotlin)

@Query

Let’s say you have a URL that uses pagination to get the JSON data(e.g., https://reqres.in/api/users?page=2), you can change the number of the page by using the @Query("page") annotation.

So, in your APIService.kt file:

interface APIService { // ... // Request using @Query (e.g https://reqres.in/api/users?page=2) @GET("/api/users") suspend fun getEmployees(@Query("page") page: String?): Response<ResponseBody> // ... }
Code language: Kotlin (kotlin)

And in your GET request, set the page like:

val response = service.getEmployees("2") // We're getting a list of users from the page 2
Code language: Kotlin (kotlin)

Updating data using PUT method

To update the data on the server, you need to use the HTTP request method PUT, which is almost the same as the POST method.

Go to your APIService.kt file and add the @PUT annotation with the path of the URL:

interface APIService { // ... @PUT("/api/users/2") suspend fun updateEmployee(@Body requestBody: RequestBody): Response<ResponseBody> // ... }
Code language: Kotlin (kotlin)

Then, create a new PUT request:

fun putMethod() { // Create Retrofit val retrofit = Retrofit.Builder() .baseUrl("https://reqres.in") .build() // Create Service val service = retrofit.create(APIService::class.java) // Create JSON using JSONObject val jsonObject = JSONObject() jsonObject.put("name", "Nicole") jsonObject.put("job", "iOS Developer") // Convert JSONObject to String val jsonObjectString = jsonObject.toString() // Create RequestBody ( We're not using any converter, like GsonConverter, MoshiConverter e.t.c, that's why we use RequestBody ) val requestBody = jsonObjectString.toRequestBody("application/json".toMediaTypeOrNull()) CoroutineScope(Dispatchers.IO).launch { // Do the PUT request and get response val response = service.updateEmployee(requestBody) withContext(Dispatchers.Main) { if (response.isSuccessful) { // Convert raw JSON to pretty JSON using GSON library val gson = GsonBuilder().setPrettyPrinting().create() val prettyJson = gson.toJson( JsonParser.parseString( response.body() ?.string() // About this thread blocking annotation : https://github.com/square/retrofit/issues/3255 ) ) Log.d("Pretty Printed JSON :", prettyJson) } else { Log.e("RETROFIT_ERROR", response.code().toString()) } } } }
Code language: Kotlin (kotlin)

Removing data using DELETE method

To delete the data from the server, you need to use the HTTP request method DELETE.

In the APIService.kt file, add the @DELETE annotation with the path of the URL you want to delete:

interface APIService { // ... @DELETE("/typicode/demo/posts/1") suspend fun deleteEmployee(): Response<ResponseBody> // ... }
Code language: Kotlin (kotlin)

And make a DELETE request:

fun deleteMethod() { // Create Retrofit val retrofit = Retrofit.Builder() .baseUrl("https://my-json-server.typicode.com/") .build() // Create Service val service = retrofit.create(APIService::class.java) CoroutineScope(Dispatchers.IO).launch { // Do the DELETE request and get response val response = service.deleteEmployee() withContext(Dispatchers.Main) { if (response.isSuccessful) { // Convert raw JSON to pretty JSON using GSON library val gson = GsonBuilder().setPrettyPrinting().create() val prettyJson = gson.toJson( JsonParser.parseString( response.body() ?.string() // About this thread blocking annotation : https://github.com/square/retrofit/issues/3255 ) ) Log.d("Pretty Printed JSON :", prettyJson) } else { Log.e("RETROFIT_ERROR", response.code().toString()) } } } }
Code language: Kotlin (kotlin)

In this example, the URL I’m using for the DELETE method doesn’t return any response after deleting the item. That’s why the results are empty.

You can find the final project here

If you have any questionsplease feel free to leave a comment below

Subscribe
Notify of
guest
4 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

Get once a week my latest tutorials right in your inbox

Check your inbox to confirm your email