How to Create an HTTP Request in Kotlin
- Create a Kotlin Project and Add Dependencies
-
Use
Retrofit
to Create an HTTP Request in Kotlin - Use an API of the Java Standard Library to Create an HTTP Request in Kotlin
-
Use the
Fuel
API to Create an HTTP Request in Kotlin -
Use the
OkHttp
API to Create an HTTP Request in Kotlin - Conclusion
HTTP is a communication protocol for the web and is responsible for serving web content from a web server to the web browser.
The web content might be static data or dynamic data. Static data means that information displayed on a page does not change, while dynamic data displayed on a web page is always changing.
The data retrieved from a server include structured data, image and video files. Most applications usually work with structured data, which is managed by a database.
A common approach when fetching data from the database to the web client is using restful APIs. The restful APIs are consumed by the application using different libraries through the HTTP protocol and loaded to the web client.
In this tutorial, we will learn the different ways we can use to create an HTTP request that consumes a Restful API. The Restful API returns a list of countries from an application hosted on Heroku
.
Create a Kotlin Project and Add Dependencies
Open the IntelliJ development environment and select File
> New
> Project
. On the window that opens, enter the project name
as kotlin-http-request
, select Kotlin
on the Language
section, and select Gradle
on the Build system
section.
Finally, press the Create
button to generate the project.
Open the file build.gradle.kts
and ensure you have all the dependencies shown in the following code. These dependencies help us add the libraries we can use to create HTTP requests.
dependencies{
implementation ("com.squareup.retrofit2:retrofit:2.9.0")
implementation ("com.squareup.retrofit2:converter-gson:2.9.0")
implementation ("com.github.kittinunf.fuel:fuel:2.3.1")
implementation ("com.squareup.okhttp3:okhttp:4.10.0")
testImplementation(kotlin("test"))
}
Use Retrofit
to Create an HTTP Request in Kotlin
Retrofit
is the most commonly used library when developing applications with either Kotlin or Java.
Under the kotlin
folder, create a folder named model
. Create a file named Country.kt
and copy and paste the following code into the file.
package model
data class Country(var id: Number,
var countryName: String);
In this code, we have created a data class
that we will use to store the country
objects fetched from the server. The class has fields id
and countryName
, which will be mapped with the fields of the objects retrieved from the server.
Under the kotlin
folder, create a folder named service
. Create a file named CountryService.kt
and copy and paste the following code into the file.
package service
import model.Country
import retrofit2.Call
import retrofit2.http.GET
interface CountryService {
@GET("/country/all")
fun getAllCountries(): Call<List<Country>>;
}
In this code, we have created a GET
request that maps to the relative path /country/all
to fetch all countries List<Country>
from the server. We always use the @GET
annotation when we want to retrieve data from a server.
Note that the getAllCountries()
method returns a Call
which means that the method makes a request to the server and returns a response.
Create a file named CountryServiceImpl.kt
and copy and paste the following code into the file.
package service
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class CountryServiceImpl {
fun getCountryServiceFactory(): CountryService{
val retrofit = Retrofit.Builder()
.baseUrl("https://countryapp254.herokuapp.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit.create(CountryService::class.java);
}
}
This class does the main work of fetching the data from the server by mapping the relative URL we provided in the getAllCountries()
method with the baseUrl()
provided to the builder.
The addConverterFactory()
helps us to deserialize the Kotlin objects using the Gson
library, which is also provided by Retrofit
.
Create a Main.kt
file under the kotlin
folder and copy and paste the following code into the file.
import model.Country
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import service.CountryService
import service.CountryServiceImpl
fun getAllCountriesUsingRetrofit(){
val countryService: CountryService =
CountryServiceImpl().getCountryServiceFactory();
val call: Call<List<Country>> = countryService.getAllCountries();
call.enqueue(object : Callback<List<Country>> {
override fun onResponse(call: Call<List<Country>>,
response: Response<List<Country>>
) {
response.body()?.forEach(::println)
}
override fun onFailure(call: Call<List<Country>>, t: Throwable) {
t.printStackTrace();
}
})
}
fun main(){
getAllCountriesUsingRetrofit();
}
The above code verifies whether our Retrofit code is working. Invoke the getCountryServiceFactory()
which returns a CountryService
.
The CountryService
instance helps us to call the getAllCountries()
method. The method returns a Call
that contains a response to our data.
To get the countries retrieved from the server, call the enqueue()
method and implement the onResponse()
and onFailure()
methods of the CallBack
.
The enqueue()
method executes asynchronously, and since we are creating a console application, we only need to log the response body()
to the console. Run this code and ensure the output is as shown below.
[{"id":18,"countryName":"Kenya"},
{"id":20,"countryName":"Tanzania"},
{"id":21,"countryName":"Ethiopia"},
{"id":22,"countryName":"Malawi"},
{"id":23,"countryName":"Country"},
{"id":24,"countryName":"Country"},
{"id":25,"countryName":"Kenya"},
{"id":26,"countryName":"Country"},
{"id":27,"countryName":"USA"},
{"id":28,"countryName":"USA"},
{"id":29,"countryName":"Kenya"},
{"id":30,"countryName":"Kenya"}]
Use an API of the Java Standard Library to Create an HTTP Request in Kotlin
Comment on the previous example in the Main.kt
file and copy and paste the following code into the file after it.
import java.net.HttpURLConnection
import java.net.URL
fun getCountriesUsingHttpURLConnection(){
var url = URL("https://countryapp254.herokuapp.com/country/all");
with(url.openConnection() as HttpURLConnection){
inputStream.bufferedReader().use {
it.lines().forEach(::println)
}
}
}
fun main(){
getCountriesUsingHttpURLConnection();
}
The URLConnection
is an API of the Java standard library from the java.net
package and can be used in Kotlin to make HTTP requests.
The HttpURLConnection
is an instance of URLConnection
, and we use it to create an HTPP connection to our server. The with()
function makes a single request to the server using the established connection, executes the code inside the function, and returns our result.
The inputStream
inside the function reads the data from the established connection using a bufferedReader()
and the use()
extension function helps us to log the data read from the server to the console. Run this code and ensure the output is as shown below.
[{"id":18,"countryName":"Kenya"},
{"id":20,"countryName":"Tanzania"},
{"id":21,"countryName":"Ethiopia"},
{"id":22,"countryName":"Malawi"},
{"id":23,"countryName":"Country"},
{"id":24,"countryName":"Country"},
{"id":25,"countryName":"Kenya"},
{"id":26,"countryName":"Country"},
{"id":27,"countryName":"USA"},
{"id":28,"countryName":"USA"},
{"id":29,"countryName":"Kenya"},
{"id":30,"countryName":"Kenya"}]
Use the Fuel
API to Create an HTTP Request in Kotlin
Comment on the previous example in the Main.kt
file and copy and paste the following code into the file after it.
import com.github.kittinunf.fuel.httpGet
import com.github.kittinunf.result.Result
fun getCountriesUsingFuel(){
val request = "https://countryapp254.herokuapp.com/country/all"
.httpGet()
.responseString{ request, response, result ->
when(result){
is Result.Failure -> {
println(result.getException());
}
is Result.Success -> {
println(result.get())
}
}
}
request.join();
}
fun main(){
getCountriesUsingFuel();
}
The Fuel
API is another approach we can use to create HTTP requests in our applications. In this example, we have called the httpGet()
, an extension function of the String
class, to indicate that we are making a GET
request.
The string provides the RESTful API used to fetch data from the server.
The httpGet()
method returns a Request
which allows us to call the responseString()
method to execute the request asynchronously into a Charset.UTF-8
by passing a handler as the argument.
The handler is a lambda function that accepts three parameters of type Request
, Response
, and Result
and returns a Unit
which means it does not return any value. Since we are interested in the Result
, we invoke Failure
and Success
which both provide a result when the application failed or succeeded, respectively.
The when()
method is the same as switch
in Java and helps us make different decisions when the request was successful or failed. Run this code and ensure the output is as shown below.
[{"id":18,"countryName":"Kenya"},
{"id":20,"countryName":"Tanzania"},
{"id":21,"countryName":"Ethiopia"},
{"id":22,"countryName":"Malawi"},
{"id":23,"countryName":"Country"},
{"id":24,"countryName":"Country"},
{"id":25,"countryName":"Kenya"},
{"id":26,"countryName":"Country"},
{"id":27,"countryName":"USA"},
{"id":28,"countryName":"USA"},
{"id":29,"countryName":"Kenya"},
{"id":30,"countryName":"Kenya"}]
Use the OkHttp
API to Create an HTTP Request in Kotlin
Comment on the previous example in the Main.kt
file and copy and paste the following code into the file after it.
import okhttp3.OkHttpClient
import okhttp3.Request
private val httpClient = OkHttpClient()
fun getCountriesUsingOkHttp() {
val countriesRequest = Request.Builder()
.url("https://countryapp254.herokuapp.com/country/all")
.build();
httpClient.newCall(countriesRequest).execute().use { countryResponse ->
if (!countryResponse.isSuccessful) throw RuntimeException("status code $countryResponse");
println(countryResponse.body!!.string())
}
}
fun main(){
getCountriesUsingOkHttp();
}
The OkHttpClient()
creates a shared API instance that we can use to make HTTP requests to the server.
The shared instance is created because each client has its thread pools and connections pools, and reusing them is important to save on memory and reduce latency.
The Builder()
creates a Request
using the provided URL
, and to prepare a request to the server, we invoke the newCall()
method from the OkHttpClient()
instance and pass the Request
as the argument of this method.
The newCall()
method returns a Call
and we invoke its execute()
method to get the response of the request from Response.body()
. The use()
extension function helps us access the response’s data and log it to the console.
Note that the use()
function closes the result regardless of whether an exception was thrown or not. Run this code and ensure the output is as shown below.
[{"id":18,"countryName":"Kenya"},
{"id":20,"countryName":"Tanzania"},
{"id":21,"countryName":"Ethiopia"},
{"id":22,"countryName":"Malawi"},
{"id":23,"countryName":"Country"},
{"id":24,"countryName":"Country"},
{"id":25,"countryName":"Kenya"},
{"id":26,"countryName":"Country"},
{"id":27,"countryName":"USA"},
{"id":28,"countryName":"USA"},
{"id":29,"countryName":"Kenya"},
{"id":30,"countryName":"Kenya"}]
Conclusion
In this tutorial, we have learned different ways that we can leverage to create HTTP requests in Kotlin. The approaches we covered include using Retrofit
, using an API of the Java standard library, using the Fuel
API, and finally covered using the OkHttp
API.
Note that these are not the only approaches we can use; there are other approaches that we can use, such as the Volley
API. Feel free to use any method that is suitable for your use case.
David is a back end developer with a major in computer science. He loves to solve problems using technology, learning new things, and making new friends. David is currently a technical writer who enjoys making hard concepts easier for other developers to understand and his work has been published on multiple sites.
LinkedIn GitHub