How to make an API request in Kotlin?

AndroidRestKotlin

Android Problem Overview


I am extremely new to Kotlin and APIs in general and can't find the syntax to create an API request using this language. I am creating a mobile version of a website so I'm using Android Studio to create a new UI for an already established backend. What are the steps and syntax to creating a request? Any help is deeply appreciated.

Android Solutions


Solution 1 - Android

Once you have set your Android Studio to use Kotlin is pretty simple to do a REST call, and it's pretty much the same logic as with Java.


Here's an example of a REST call with OkHttp:

build.gradle

dependencies {
    //...
    implementation 'com.squareup.okhttp3:okhttp:3.8.1'
}

AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />

MainActivity.kt

class MainActivity : AppCompatActivity() {

    private val client = OkHttpClient()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        run("https://api.github.com/users/Evin1-/repos")
    }

    fun run(url: String) {
        val request = Request.Builder()
                .url(url)
                .build()

        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {}
            override fun onResponse(call: Call, response: Response) = println(response.body()?.string())
        })
    }
}

Below are a few more complicated examples with other libraries:

Solution 2 - Android

you can use Retrofit or AsyncTask , example of AsyncTask :

class getData() : AsyncTask<Void, Void, String>() {
    override fun doInBackground(vararg params: Void?): String? {
    }

    override fun onPreExecute() {
        super.onPreExecute()
    }

    override fun onPostExecute(result: String?) {
        super.onPostExecute(result)
    }
}

for Retrofit check this awsome tutorial

Solution 3 - Android

I have create a sample API call using retrofit 2. Firstly, add these libraries in gradle

implementation "com.squareup.retrofit2:retrofit:2.3.0"
implementation "com.squareup.retrofit2:adapter-rxjava2:2.3.0"
implementation "com.squareup.retrofit2:converter-gson:2.3.0"
implementation "io.reactivex.rxjava2:rxandroid:2.0.1"

then create a class to configure Retrofit 2, say Connect.kt

class Connect {

    companion object {

        private fun getRetrofit(Url:String):Retrofit {
            return Retrofit.Builder()
                    .addCallAdapterFactory(
                            RxJava2CallAdapterFactory.create())
                    .addConverterFactory(
                            GsonConverterFactory.create())
                    .baseUrl(Url)
                    .build()
        }

        fun getApiData():Retrofit{
            val retrofitApi = getRetrofit(Url.BASE_URL)
            return retrofitApi
        }

        fun callApi():CallApi{
            val retrofitCall = getApiData()
            return retrofitCall.create(CallApi::class.java)
        }

    }
}

I have created Url in Url class say Url.kt

class Url {
    companion object {
        const val BASE_URL = "your base url"
        const val URL = "your url"
    }
}

Created an interface for Api call

    interface CallApi {
    
        @GET(Url.URL)
//query needed if there is any query
        fun getApi(@Query("limit") limit: Int):
//model class is needed                
Observable<Model.Result>
    }

Create a model class according to your response, sample response is

{
    "data": {
        "children": [
            {
                "data": {
                    "author": "",
                     "thumbnail":"",
                      "title":""
                     }
                 }]
          }
 }

for creating its model class, create an object say, Model

object Model {
    data class Result(val data: Data)
    data class Data(val children: List<Children>)
    data class Children(val data: Datas)
    data class Datas(val author: String,val thumbnail: String,val title: String)
}

Then create a boiler plate class to perform data fetch from api which can be called from any activity

class ApiData {
    companion object {
        const val count = 10
        val api by lazy { Connect.callApi() }
        var disposable: Disposable? = null
        fun apiData(callback:Response){
            disposable = api.getApi(count)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe ({
                        result ->
                        callback.data(result,true)
                    }, { error ->
                        error.printStackTrace()
                    })

        }

    }
    interface Response {
        fun data(data:Model.Result,status:Boolean)
    }
}

now it can be called from activity like,

ApiData.apiData( object :ApiData.Response{
    override fun data(data: Model.Result, status: Boolean) {
        if(status){
            val items:List<Model.Children> = data.data.children
        }
    }

})

Solution 4 - Android

First add permission in AndroidManifest.xml

  <uses-permission android:name="android.permission.INTERNET" />

Second, install the Google dependency, Volley package

obs: volley is the official Google package for making JSON calls

link: https://github.com/google/volley

access project structure enter image description here

click in Dependencies

enter image description here

in all Dependencies click in + enter image description here

click in Library Denpendency

enter image description here

find to volley and click Search

enter image description here

after you click in ok click in Apply, done.

create a new Class called RequestJSON, in my case i'm using Kotlin

  import android.app.Activity
  import com.android.volley.*;
  import com.android.volley.toolbox.JsonObjectRequest
  import com.android.volley.toolbox.Volley
  import org.json.JSONObject
  import java.lang.Exception

  class RequestJSON {
      private val baseURL: String = "[PROTOCOL]://[HOST]:[PORT]/";
      private var url: String = "";
      private var method: String = "GET";
      private var requestData: JSONObject = JSONObject();
      private var queryString: String = "";

      companion object Factory {
          fun instance(): RequestJSON = RequestJSON();
      }

      fun setURL(url: String): RequestJSON {
          this.url = url;
          return this;
      }

      fun setMethod(method: String): RequestJSON {
          this.method = method.toLowerCase();
          return this;
      }

      fun setData(data: JSONObject): RequestJSON {
          this.requestData = data;
          return this;
      }

      private fun appendQuery(array: Array<String>, element: String): Array<String> {
          val list: MutableList<String> = array.toMutableList();
          list.add(element);

          return list.toTypedArray();
      }

      fun setQuery(query: JSONObject) : RequestJSON {
          // limpa o queryString
          this.queryString = "";

          // obtendo as chaves do json
          val keys = query.keys();
          // criando array para conter as querys
          var querys: Array<String> = arrayOf();

          // obtendo os valores atravéz da chave e adicionando no array
          for(key in keys) {
              querys = this.appendQuery(querys, key + "=" + query.get(key));
          }

          // verifica se existe valores no array
          // para conversão em stringQuery
          if (querys.size > 0) {
              this.queryString += "?";
              val size = querys.size;
              var count = 0;

              while (count < size) {
                  var querystring = "";

                  if (count == 0) {
                      querystring = querys[count];
                  } else {
                      querystring = "&" + querys[count];
                  }

                  this.queryString += querystring;
                  count++;
              }
          }

          return this;
      }

      private fun getMethod(): Int {
          return when(this.method) {
              "get" -> {
                  Request.Method.GET;
              }
              "post" -> {
                  Request.Method.POST;
              }
              "put" -> {
                  Request.Method.PUT;
              }
              "delete" -> {
                  Request.Method.DELETE;
              }
              else -> Request.Method.GET;
          }
      }

      fun send(context: Activity, responseListiner: (response: JSONObject) -> Unit, errorListiner: (error: Exception) -> Unit) {
          val queue = Volley.newRequestQueue(context);
          var url = this.baseURL + this.url + this.queryString;
          var data: JSONObject = this.requestData;

          // limpando queryString após ser utilizado
          this.queryString = "";
          // limpando url após ser utilizado
          this.url = "";
          // limpando requestData após ser utilizado
          this.requestData = JSONObject();

          val jsonObjectRequest = JsonObjectRequest(this.getMethod(), url, data, fun (response) {
              responseListiner(response);
          }, fun (error) {
              errorListiner(error);
          })

          // adicionando requesição ao queue
          queue.add(jsonObjectRequest);
      }
  }

to test use

fun responseApiSuccess(response: JSONObject) {
    Log.i("request-success", response.toString());
}

fun responseApiError(error: Exception) {
    Log.e("request-error", error.toString());
}

fun callAPI() {
    var queryObject: JSONObject = JSONObject();

    queryObject.put("teste", "valor01");

    try {
        RequestJSON.instance().setURL("/").setMethod("GET").setQuery(queryObject).send(this, this::responseApiSuccess, this::responseApiError);
    } catch (error: Exception) {
        error.printStackTrace();
    }
}

Solution 5 - Android

Retrofit is a good tool to consume API's on Android. Here is a tutorial I found on how to use Retrofit on Kotlin

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNuttersView Question on Stackoverflow
Solution 1 - AndroidEvin1_View Answer on Stackoverflow
Solution 2 - AndroidOussema ArouaView Answer on Stackoverflow
Solution 3 - AndroidRejsalView Answer on Stackoverflow
Solution 4 - AndroidJoão Victor PalmeiraView Answer on Stackoverflow
Solution 5 - AndroidMacLean SochorView Answer on Stackoverflow