Intro to Android Development
  • Welcome
  • Syllabus
  • Hack Challenge
  • Resources
    • Lecture Videos
    • Ed Discussion
    • Git & GitHub Help/How-To
    • Setting up Android Studio
    • Starting an Android Studio Project & Making an Emulator
    • Importing, Exporting, & Submitting Your Projects to CMS
  • SP25 Course Material
    • Week 1 | Course Logistics, Kotlin, & Basic UI
      • Relevant Links
      • Demo/Lecture: Eatery Card
      • A0: Eatery Card (Follow-Along)
    • Week 2 | States, Components, LazyColumn
      • Relevant Links
      • Demo: Todo List
      • A2: Shopping List
    • Week 3 | Navigation & Animations
      • Relevant Links
      • Demo: Onboarding
      • A3: Stock Trading (RobbingGood)
    • Week 4 | MVVM and Flows
      • Relevant Links
      • Demo: Eatery Card 2
      • A4: Chat of a Lifetime
    • Week 5 | Dumb Components & UIEvents
      • Relevant Links
      • Demo: Music Player
      • A5: Rate My Vibe
    • Week 6 | Coroutines, Networking, JSON
      • Relevant Links
      • Demo: Retrofit
      • A6: You Should Even Lift, Bro.
  • Bonus Week | Android Job Search
    • Relevant Links
    • Android Technical Interview Question!
  • Textbook
    • 1. Introduction to the Editor and Views
      • 1.1 Introduction to the Editor
      • 1.2 SDK Management
      • 1.3 Kotlin Overview
      • 1.4 Views
      • 1.5 Android Studio Project Demo + Understanding The Editor
    • 2. Jetpack Compose
      • 2.1 Introduction
      • 2.2 Layouts
      • 2.3 Modifiers
      • 2.4 Animations
      • 2.5 Lazy Lists
      • 2.6 Reactive UI
    • 3. Intents and Manifest
      • 3.1 Activities
      • 3.2 Implicit Intents
      • 3.3 Explicit Intents
      • 3.4 Manifest
      • 3.5 Permissions
      • 3.6 Summary
    • 4. Navigation
      • 4.1 Types of Navigation
      • 4.2 Implementation of the Bottom Navigation Bar
    • 5. Data and Persistent Storage
      • 5.1 Singleton Classes
      • 5.2 Shared Preferences
      • 5.3 Rooms
      • 5.4 Entities
      • 5.5 Data Access Objects
      • 5.6 Databases
    • 5.5 Concurrency
      • 5.5.1 Coroutines
      • 5.5.2 Implementation of Coroutines
      • 5.5.3 Coroutines with Networking Calls
    • 6. Networking and 3rd Party libraries
      • 6.1 HTTP Overview
      • 6.2 3rd Party Libraries
      • 6.3 JSON and Moshi
      • 6.4 Retrofit
      • 6.5 Summary
    • 7. MVVM Design Pattern
      • 7.1 Key Idea
      • 7.2 Implementation Ideas
    • 8. Flows
    • 9. The Art and Ontology of Software
    • 10. 🔥 Firebase
      • 10.1 Setting up Firebase
      • 10.2 Authentication
      • 10.3 Analytics
      • 10.4 Messaging
      • 10.5 Firestore
  • Additional Topics
    • Git and GitHub
    • Exporting to APK
  • Archive
    • Archived Native Android Textbook Pages
      • 1. Layouts and More Views
        • 1.1 File Structure and File Types
        • 1.2 Resource Files
        • 1.3 Button and Input Control
        • 1.4 ViewGroups
        • 1.5 Summary + A Note On Chapter 2 Topics
      • 2. RecyclerViews
        • 2.1 RecyclerViews
        • 2.2 RecyclerView Performance
        • 2.3 Implementation of a Recycler View
        • 2.4 Implementation with Input Controls
        • 2.5 Filtering RecyclerViews
        • 2.6 Recyclerview Demo
      • 3. ListViews and Searching
        • 3.1 ListView vs. RecyclerView
        • 3.2 ListView Performance
        • 3.3 Implementation of a ListView
        • 3.4 Searching in a List View
      • 4. Fragments
        • 4.1 What are Fragments?
        • 4.2 Lifecycle of a Fragment
        • 4.3 Integrating a Fragment into an Activity
        • 4.4 Sharing Data Between Fragments
        • 4.5 Fragment Slide Shows
      • 5. OkHttp
      • 6. Activity Lifecycle
      • 7. Implementation of Tab Layout
    • Fall 2024 Course Material
      • Lecture 1 & Exercise 1: Introduction to Android
      • Lecture 1.5: Beauty of Kotlin
      • Lecture 2 & HW 2: Modifiers, Lazylists and Reactive UI
      • Lecture 3 & HW 3: Animations, Intents and Manifest
      • Lecture 4 & HW 4: Coroutines & Navigation
      • Lecture 5 & HW 5: Persistent Storage, Networking, and JSON Parsing
      • Lecture 6 & HW 6: MVVM, Flows
      • Bonus Lectures & Bonus HW
      • Bonus Lecture: Industry Practice
    • Spring 2024 Course Material
      • Lecture 1 & Exercise 1: Introduction to Android
      • Lecture 4 & HW 4: LazyLists
      • Lecture 6 & HW 6: Networking, Data, and Persistent Storage
    • Spring 2020 Course Material
      • Week 1: Intro to the Editor
      • Week 2: Views and Layouts
      • Week 3: Intent and Manifest
      • Week 4: ListView and RecyclerView
      • Week 5: Fragments
      • Week 6: Networking
    • Spring 2021 Lecture & HW 8: Networking & 3rd Party APIs
    • HackOurCampus Workshop
Powered by GitBook
On this page
  • What is Retrofit?
  • Why Use Moshi?
  • API Documentation: The Starting Point
  • Setting Up Retrofit and Moshi in Your Project
  • Step 1: Model Your Data with Kotlin Data Classes
  • Step 2: Define the API Interface
  • Step 3: Create a Retrofit Instance in a Singleton
  • Step 4: Making Network Requests

Was this helpful?

  1. Textbook
  2. 6. Networking and 3rd Party libraries

6.4 Retrofit

Retrofit is a type-safe HTTP client for Android and Java that allows you to retrieve or upload data through a REST-based web service. Let's go through how you can set up Retrofit, integrate Moshi for JSON parsing, and make network requests that handle your API data like a pro!

What is Retrofit?

Retrofit is a type-safe library that simplifies the process of making HTTP requests and converting responses. Instead of writing tons of boilerplate code for HTTP clients, Retrofit lets you define your API routes as Kotlin interfaces and converts them into functions. You can describe each route using annotations like @GET, @POST, @PUT, and @DELETE.

For example, let’s say you want to retrieve data from a RESTful API. Using Retrofit, you’ll create an interface that defines API routes as functions, specifying the type of request (GET, POST, etc.) and any parameters required. Once this interface is ready, you can call these functions as if they were native Kotlin functions.

Why Use Moshi?

When your app communicates with APIs, it will often receive data in JSON format. Instead of manually converting JSON to Kotlin objects, Moshi does this for you. As we discussed in the previous section Moshi allows for the automatic interpretation of JSON objects into Kotlin data classes, making it much easier to handle incoming and outgoing data from the API.

API Documentation: The Starting Point

Before diving into the code, ensure you have the API documentation from your web service. This will tell you:

  • How to call certain API requests.

  • What parameters are required.

  • What the API returns.

You’ll use this information to model your data and define your Retrofit interfaces.

Setting Up Retrofit and Moshi in Your Project

First, you'll need to add the necessary dependencies to your project. Open your build.gradle.kts file and include the following lines:

dependencies {
    implementation("com.squareup.retrofit2:retrofit:2.9.0")
    implementation("com.squareup.moshi:moshi-kotlin:1.14.0")
    ksp("com.squareup.moshi:moshi-kotlin-codegen:1.15.1")
    implementation("com.squareup.retrofit2:converter-moshi:2.9.0")
}

plugins {
    id("com.google.devtools.ksp").version("2.0.0-1.0.24")
}

Additionally, don't forget to add internet permissions to your AndroidManifest.xml file:

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

Step 1: Model Your Data with Kotlin Data Classes

You’ll need to create data models that represent the structure of the JSON data you’re working with. This is where Moshi comes into play. Use @JsonClass and @Json annotations to map the JSON fields to your Kotlin data class fields.

Here’s an example of how you can model a simple user data object:

data class User(
    @Json(name = "id") val userId: Int,
    @Json(name = "name") val userName: String,
    @Json(name = "email") val userEmail: String
)

Step 2: Define the API Interface

Next, define your API routes by creating an interface. Use annotations like @GET, @POST, @PUT, etc., to specify the HTTP method for each endpoint. You can also include headers, query parameters, or path variables with special annotations.

Here’s how you can define an API interface to fetch user data:

interface UserService {
    @GET("users/{id}")
    @Headers("API_KEY: {your_api_key}")
    suspend fun getUser(
        @Path("id") userId: Int,
    ): User
}

Step 3: Create a Retrofit Instance in a Singleton

You should create a singleton Retrofit instance to make network requests throughout your app. You’ll configure Retrofit to use the Moshi converter for JSON handling.

object RetrofitInstance {
    
    private const val BASE_URL = "https://api.example.com/"

    private val retrofit by lazy {
        Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(MoshiConverterFactory.create())
            .build()
    }

    val api: UserService = retrofit.create(UserService::class.java)
    
}

This singleton creates a Retrofit instance with the Moshi converter and provides access to the API interface UserService.

Step 4: Making Network Requests

Now that everything is set up, making a network request is as simple as calling the interface function. Since you’re likely to use coroutines for asynchronous calls, don’t forget to run your network request in a coroutine context.

val scope = rememberCoroutineScope()
fun fetchUser(userId: Int, authToken: String) {
    scope.launch {
        withContext(Dispatchers.IO){
            try {
                val user = RetrofitInstance.api.getUser(userId, authToken)
                println("User fetched: $user")
            } catch (e: Exception) {
                println("Error fetching user: ${e.message}")
            }
        }
    }
}
  • We use CoroutineScope with Dispatchers.IO to run the network request on a background thread.

  • The getUser function is called, fetching the user data based on the provided userId and authToken.

  • If the request is successful, the user data is printed. Otherwise, an error message is shown.

By using Retrofit with Moshi, you can make your network code cleaner, more readable, and easy to maintain. No more manually parsing JSON or writing complex HTTP clients from scratch—Retrofit and Moshi handle all of that for you. Whether you're building a small app or working on a large project, this setup simplifies making reliable API calls in Kotlin.

Previous6.3 JSON and MoshiNext6.5 Summary

Last updated 6 months ago

Was this helpful?