Android HTTPS Request

This tutorial details how to make HTTPS GET requests, in Kotlin, with Retrofit: a networking library for Android.

In this way, a mobile client is build to communicate with a third party.

Namely, the aim is to get countries from the backend, REST Countries APIs, to illustrate HTTPS GET requests.

Note: Retrofit version 2.9 is used (latest version to date).

Following, the steps of implementation:

  • Configure the AS project to use networking libraries
  • Analyze the expected results
  • Create the models
  • Create the API interface
  • Make requests

Configure the AS project to use networking libraries

First of all, it's about adding the internet permission in aim of authorizing the application to connect to the internet.

In addition, networking libraries are added to the Android Studio project, in dependencies section:

  • Retrofit to create a client and make HTTPS requests
  • Moshi to convert into Kotlin objects the JSON results received from server
  • OkHttp to deal with backward compatibility
  1. Create a new Android project, let's name it WonderfulWorld, with Empty Activity as project template.
  2. Add the internet permission, in the AndroidManifest.xml file, between <manifest> and <application/> tags:

                                              <uses-permission                      android:name=                      "android.permission.INTERNET"                      />                                      
  3. In the Gradle Script file attached to the app module, include these 3 libraries:

                                              dependencies                      {                      implementation                      "com.squareup.retrofit2:retrofit:$retrofit_version"                      implementation                      "com.squareup.retrofit2:converter-moshi:$moshi_version"                      implementation                      "com.squareup.okhttp3:okhttp:$okhttp_version"                      }                                      
  4. In the Gradle Script file attached to the whole project, add the version variables:

                                              ext                      .                      retrofit_version                      =                      '                      2.9                      .                      0                      '                      ext                      .                      moshi_version                      =                      '                      2.9                      .                      0                      '                      ext                      .                      okhttp_version                      =                      '                      4.9                      .                      0                      '                                      

Analyze the expected results

The aim is to find, test HTTPS requests and then dissect the results with Postman.

  1. Let us begin with this simple HTTPS request:

                                              https://restcountries.eu/rest/v2/all                                      
  2. Following is an extract of the results from Postman:

                                              [    {        "name": "Afghanistan",        "topLevelDomain": [            ".af"        ],        "alpha2Code": "AF",        "alpha3Code": "AFG",        "callingCodes": [            "93"        ],        "capital": "Kabul",        "altSpellings": [            "AF",            "Afġānistān"        ],        "region": "Asia",        "subregion": "Southern Asia",        "population": 27657145,        "latlng": [            33.0,            65.0        ],        "demonym": "Afghan",        "area": 652230.0,        "gini": 27.8,        "timezones": [            "UTC+04:30"        ],        "borders": [            "IRN",            "PAK",            "TKM",            "UZB",            "TJK",            "CHN"        ],        "nativeName": "افغانستان",        "numericCode": "004",        "currencies": [            {                "code": "AFN",                "name": "Afghan afghani",                "symbol": "؋"            }        ],        "languages": [            {                "iso639_1": "ps",                "iso639_2": "pus",                "name": "Pashto",                "nativeName": "پښتو"            },            {                "iso639_1": "uz",                "iso639_2": "uzb",                "name": "Uzbek",                "nativeName": "Oʻzbek"            },            {                "iso639_1": "tk",                "iso639_2": "tuk",                "name": "Turkmen",                "nativeName": "Türkmen"            }        ],        "translations": {            "de": "Afghanistan",            "es": "Afganistán",            "fr": "Afghanistan",            "ja": "アフガニスタン",            "it": "Afghanistan",            "br": "Afeganistão",            "pt": "Afeganistão",            "nl": "Afghanistan",            "hr": "Afganistan",            "fa": "افغانستان"        },        "flag": "https://restcountries.eu/data/afg.svg",        "regionalBlocs": [            {                "acronym": "SAARC",                "name": "South Asian Association for Regional Cooperation",                "otherAcronyms": [],                "otherNames": []            }        ],        "cioc": "AFG"    },    {        "name": "Åland Islands",        "topLevelDomain": [            ".ax"        ],        "alpha2Code": "AX",        "alpha3Code": "ALA",        "callingCodes": [            "358"        ],        "capital": "Mariehamn",                                      

Create the models

The aim is to create the Kotlin data classes representing the remote data.

In particular, it's about create a data class representing a country, from the REST Countries APIs. For instance, the WonderfulWord App show:

  • name of the country
  • capital
  • langages name

Moshi library convert the JSON response into objects. Firstly Country has a name, a capital and a list of language. Secondly, Language has a name. Indeed, the JSON response contains a list (indicated with []) of language objects (indicated with {}).

  1. Create the Country data class:

                                              data class                      Country                      (                      val                      name                      :                      String                      ,                      val                      capital                      :                      String                      ,                      val                      languages                      :                      List                      <                      Language                      >)                                      
  2. Create the Language data class:

                                              data class                      Language                      (                      val                      name                      :                      String                      )                                      

Note: attributes name are important and have to be exactly like in response from server.

Create the API interface

  1. Create the CountriesService interface:

                                              interface                      CountriesService                      {                      @GET                      (                      "/rest/v2/all"                      )                      fun                      listCountries                      ():                      Call                      <                      List                      <                      Country                      >>                      }                                      

Note: Be careful with imports:

                import retrofit2.Call import retrofit2.http.GET                              

Make requests

The aim is to create Retrofit client to make requests.

  1. Add the API endpoint as static variable in the MainActivity:

                                              companion                      object                      {                      const                      val                      URL_COUNTRY_API                      =                      "https://restcountries.eu/"                      }                                      
  2. Instantiate a Retrofit client in MainActivity:

                                              val                      retro                      =                      Retrofit                      .                      Builder                      ()                      .                      baseUrl                      (                      URL_COUNTRY_API                      )                      .                      addConverterFactory                      (                      MoshiConverterFactory                      .                      create                      ())                      .                      build                      ()                                      
  3. Create the service variable:

                                              val                      service                      =                      retro                      .                      create                      (                      CountriesService                      ::                      class                      .                      java                      )                                      
  4. Create the request variable:

                                              val                      countryRequest                      =                      service                      .                      listCountries                      ()                                      
  5. Create the request, then send it async:

                                              countryRequest                      .                      enqueue                      (                      object                      :                                            Callback                      <                      List                      <                      Country                      >>                      {                      override                      fun                      onResponse                      (                      call                      :                      Call                      <                      List                      <                      Country                      >>,                      response                      :                      Response                      <                      List                      <                      Country                      >>)                      {                      val                      allCountry                      =                      response                      .                      body                      ()                      for                      (                      c                      in                      allCountry                      !!                      )                      Log                      .                      v                      (                      MainActivity                      ::                      class                      .                      simpleName                      ,                      "NAME: ${c.name} \n CAPITAL: ${c.capital} \n Language: ${c.languages} "                      )                      }                      override                      fun                      onFailure                      (                      call                      :                      Call                      <                      List                      <                      Country                      >>,                      t                      :                      Throwable                      )                      {                      Log                      .                      i                      (                      MainActivity                      ::                      class                      .                      simpleName                      ,                      "on FAILURE!!!!"                      )                      }                      })                                      

    The response is in the allCountry variable. If not, make sure you have access to the internet on your smartphone (or your laptop if you're using an emulator).

References

  1. Retrofit
  2. Okhttp
  3. Moshi
  4. Postman

Share or react on Twitter.

Found a typo or want to improve this post? Edit it directly!

Comments