Moshi: konsep kunci, pustaka JSON Kotlin dan cara kerjanya

Penulis: IT Sectr Diterbitkan: 2026-03-15 Waktu membaca: 8 mnt

Moshi adalah pustaka JSON modern dari Square, dibuat khusus untuk Kotlin dan Android dengan mempertimbangkan keterbatasan Gson. Ini sepenuhnya kompatibel dengan null-safety Kotlin, menghasilkan kode pada tahap kompilasi dan tidak menggunakan refleksi, yang meningkatkan kinerja dan keandalan. Menurut data Square Moshi, 2024, Moshi menyediakan serialisasi yang dapat diprediksi dan mendukung adapter kustom untuk semua tipe data.

Poin Utama

  • Moshi — pustaka JSON dari Square untuk Kotlin dan Android tanpa refleksi
  • Adapter Kotlin — dukungan bawaan untuk data class, nilai default dan null safety
  • @Json — anotasi untuk mengonfigurasi nama bidang dan mengabaikan properti
  • Adapter — logika serialisasi kustom melalui @ToJson dan @FromJson
  • Generasi kode — Moshi menghasilkan adapter pada tahap kompilasi melalui kapt atau KSP

Apa itu Moshi

Moshi adalah pustaka JSON untuk JVM, Android dan Kotlin Multiplatform, dibuat oleh Square (pembuat OkHttp dan Retrofit). Tidak seperti Gson, Moshi tidak bergantung pada refleksi — adapter dihasilkan pada tahap kompilasi melalui anotasi @JsonClass(generateAdapter = true). Ini membuat Moshi lebih cepat, lebih aman, dan lebih dapat diprediksi dalam bekerja dengan konstruksi khusus Kotlin.

Filosofi dan keunggulan

Perbedaan utama Moshi dari pendahulunya adalah penolakan refleksi. Refleksi memungkinkan Gson bekerja dengan kelas apa pun tanpa persiapan, tetapi dengan harga inisialisasi lambat, ketidakmampuan optimasi oleh compiler, dan risiko kesalahan saat runtime. Moshi memerlukan penentuan kelas secara eksplisit untuk generasi kode, tetapi sebagai imbalannya memberikan kecepatan kode yang ditulis tangan dan keamanan tipe penuh pada tahap kompilasi.

kotlin
// Menghubungkan Moshi di build.gradle
dependencies {
    implementation "com.squareup.moshi:moshi:1.15.0"
    implementation "com.squareup.moshi:moshi-kotlin:1.15.0"
    kapt "com.squareup.moshi:moshi-kotlin-codegen:1.15.0"
}

// Model sederhana dengan generasi kode
@JsonClass(generateAdapter = true)
data class User(
    @Json(name = "user_id")
    val id: Int,
    val name: String,
    val email: String,
    val avatar: String? = null
)

// Penggunaan
val moshi = Moshi.Builder()
    .build()
val jsonAdapter = moshi.adapter(User::class.java)

Instalasi dan konfigurasi

Untuk mulai bekerja dengan Moshi, perlu menambahkan dependensi di build.gradle dan menganotasi model. Moshi.Builder berfungsi sebagai titik masuk: melaluinya ditambahkan adapter bawaan untuk tipe standar, adapter kustom, dan dikonfigurasi perilaku pustaka. Moshi mendukung adapter untuk Date, Enum, Collection dan Map secara bawaan, tetapi untuk kelas Kotlin diperlukan modul moshi-kotlin. Tidak seperti Gson, Moshi tidak menggunakan refleksi untuk kelas Kotlin secara default — untuk itu KotlinJsonAdapterFactory dihubungkan, yang berfungsi sebagai opsi cadangan ketika generasi kode tidak diterapkan atau kelas tidak dianotasi dengan @JsonClass. Pendekatan ini menjamin bahwa pengembang secara eksplisit memilih antara kinerja generasi kode dan fleksibilitas refleksi untuk setiap kelas tertentu.

Membuat Moshi dan menambahkan adapter

Setelah membangun Moshi melalui Builder, pengembang mendapatkan instance Moshi dan meminta adapter untuk kelas yang diinginkan. JsonAdapter adalah objek sentral yang melakukan serialisasi melalui toJson() dan deserialisasi melalui fromJson(). Moshi secara otomatis menggunakan adapter yang dihasilkan jika kelas dianotasi dengan @JsonClass(generateAdapter = true), jika tidak, menerapkan KotlinJsonAdapterFactory reflektif sebagai opsi cadangan. Pendekatan ini menggabungkan kecepatan generasi kode dengan fleksibilitas mekanisme reflektif untuk proyek skala dan tingkat kompleksitas apa pun. Moshi sangat cocok untuk aplikasi kecil maupun proyek perusahaan besar dengan ratusan model data.

kotlin
// Mengonfigurasi Moshi dengan KotlinJsonAdapterFactory
val moshi = Moshi.Builder()
    .add(KotlinJsonAdapterFactory())
    .add(LocalDateAdapter())
    .build()

// Penggunaan adapter
val adapter = moshi.adapter(User::class.java)

// Serialisasi
val user = User(1, "Alice", "alice@test.com")
val json = adapter.toJson(user)

// Deserialisasi
val jsonString = """{"user_id":2,"name":"Bob","email":"bob@test.com"}"""
val parsedUser = adapter.fromJson(jsonString)

// Bekerja dengan daftar
val listAdapter = moshi.adapter(
    Types.newParameterizedType(
        List::class.java,
        User::class.java
    )
)

Anotasi dan adapter

Moshi menggunakan anotasi untuk mengonfigurasi serialisasi dan mendukung tipe kustom. @Json(name = "...") menetapkan kunci JSON untuk bidang. @Transient mengecualikan bidang dari serialisasi. @JsonClass(generateAdapter = true) mengaktifkan generasi kode. Untuk logika kustom, Moshi menyediakan anotasi @ToJson dan @FromJson, yang dapat ditempatkan di kelas adapter terpisah.

@Json dan adapter kustom

Anotasi @Json menggantikan @SerializedName milik Gson dan bekerja serupa: bidang kotlinName dihubungkan dengan kunci JSON “kotlin_name”. Untuk tipe yang tidak dapat diserialisasi Moshi secara default (misalnya LocalDate), pengembang membuat kelas dengan metode @ToJson dan @FromJson. Adapter didaftarkan melalui Moshi.Builder.add() dan diterapkan secara global atau untuk tipe tertentu. Moshi mendukung sealed class dan serialisasi polimorfik melalui @JsonClass dengan penunjuk diskriminator eksplisit, yang memungkinkan bekerja dengan hierarki tipe di JSON tanpa pemeriksaan bidang manual. Saat deserialisasi, Moshi secara default mengabaikan kunci yang tidak dikenal di JSON, yang memastikan kompatibilitas mundur saat menambahkan bidang baru di sisi server tanpa mengubah kode klien. Untuk debugging, mode ketat dapat diaktifkan melalui failOnUnknown, yang melempar pengecualian saat mendeteksi kunci yang tidak dikenal.

kotlin
// Adapter kustom untuk LocalDate
class LocalDateAdapter {

    @ToJson
    fun toJson(date: LocalDate): String {
        return date.format(DateTimeFormatter.ISO_LOCAL_DATE)
    }

    @FromJson
    fun fromJson(dateString: String): LocalDate {
        return LocalDate.parse(dateString)
    }
}

// Model dengan anotasi Moshi
@JsonClass(generateAdapter = true)
data class Event(
    @Json(name = "event_id")
    val id: Int,

    @Json(name = "event_date")
    val date: LocalDate,

    @Transient
    val localCache: String? = null
)

// Pendaftaran adapter
val moshi = Moshi.Builder()
    .add(LocalDateAdapter())
    .add(KotlinJsonAdapterFactory())
    .build()

Moshi vs Gson

Perbandingan Moshi dan Gson adalah pertanyaan umum saat memilih pustaka JSON untuk proyek Android. Moshi unggul dalam pengembangan Kotlin modern berkat generasi kode, null-safety, dan kecepatan. Gson tetap relevan untuk proyek Java, kode lawas, dan skenario di mana konfigurasi minimal penting. Perbedaan menjadi terlihat pada volume data besar dan model kompleks.

Kinerja dan keamanan

Uji kinerja menunjukkan bahwa Moshi dengan generasi kode bekerja 2-5 kali lebih cepat daripada Gson pada operasi serialisasi dan deserialisasi. Keunggulan utama Moshi adalah penanganan null-safety Kotlin yang benar: jika bidang tidak ada di JSON dan di model dinyatakan sebagai non-null tanpa nilai default, Moshi melempar pengecualian pada tahap deserialisasi, mencegah kesalahan tersembunyi.

KarakteristikGsonMoshi
Mekanismerefleksigenerasi kode / refleksi
Null safetytidak memperhitungkandukungan penuh Kotlin
Kecepatansedangtinggi
Nilai defaulttidak mendukungmendukung
Kotlin Multiplatformtidakya
Ukuran pustaka~240 Kb~150 Kb

Pilihan antara Moshi dan Gson tergantung pada konteks proyek. Proyek baru di Kotlin diuntungkan oleh Moshi berkat keamanan tipe dan kinerja. Gson tetap menjadi pilihan yang masuk akal untuk mendukung kode Java, struktur JSON dinamis, atau ketika kesederhanaan koneksi lebih penting daripada kecepatan. Untuk Kotlin Multiplatform, Moshi adalah satu-satunya dari dua varian yang mendukung platform ini.

Saat migrasi dari Gson ke Moshi, perubahan utama terkait anotasi dan adapter. @SerializedName milik Gson diganti dengan @Json(name = "..."), dan JsonSerializer/JsonDeserializer kustom — dengan pasangan @ToJson/@FromJson. Untuk model dengan nilai default dan bidang nullable, Moshi berperilaku lebih dapat diprediksi: jika bidang non-null tanpa nilai default tidak ada di JSON, Moshi melempar JsonDataException, mencegah NPE tersembunyi. Integrasi dengan Retrofit melalui MoshiConverterFactory ditambahkan dengan satu dependensi dan tidak memerlukan perubahan arsitektur lapisan jaringan. Untuk obfuskasi melalui ProGuard atau R8 perlu ditambahkan aturan pelestarian kelas yang dianotasi @JsonClass dan adapter yang dihasilkan, jika tidak serialisasi akan rusak di build rilis. Secara keseluruhan, migrasi dari Gson ke Moshi dibenarkan di proyek Kotlin baru di mana kinerja dan keamanan tipe penting.

kotlin
// Perbandingan serialisasi: Gson vs Moshi
data class Sample(
    val name: String,
    val count: Int,
    val tags: List<String> = listOf()
)

// Gson: bekerja melalui refleksi
val gson = Gson()
val fromGson = gson.fromJson("""{"name":"test"}""",
    Sample::class.java)
// count = 0 (default), tetapi null-safety tidak diperiksa

// Moshi: memerlukan adapter, null-safety eksplisit
@JsonClass(generateAdapter = true)
data class SampleMoshi(
    val name: String,
    val count: Int,
    val tags: List<String> = listOf()
)

Pertanyaan yang Sering Diajukan

Apa itu Moshi di Android?

Moshi adalah pustaka JSON dari Square untuk Kotlin dan Android yang menggunakan generasi kode alih-alih refleksi. Ini memberikan kinerja tinggi, penanganan null-safety Kotlin yang benar, dan kompatibilitas dengan Kotlin Multiplatform.

Apa kelebihan Moshi dibandingkan Gson?

Moshi melampaui Gson dalam kecepatan (2-5 kali lebih cepat berkat generasi kode), keamanan (memperhitungkan anotasi null Kotlin) dan ukuran (~90 Kb lebih kecil). Moshi juga mendukung Kotlin Multiplatform dan nilai default di data class.

Bagaimana cara kerja anotasi @JsonClass di Moshi?

@JsonClass(generateAdapter = true) memerintahkan Moshi untuk menghasilkan adapter untuk kelas ini pada tahap kompilasi. Adapter yang dihasilkan melakukan serialisasi secara langsung, tanpa refleksi, yang memberikan kinerja maksimal.

Bagaimana cara membuat adapter kustom Moshi?

Buat kelas dengan metode yang dianotasi dengan @ToJson (serialisasi) dan @FromJson (deserialisasi). Daftarkan instance melalui Moshi.Builder.add(). Moshi akan secara otomatis menemukan dan menerapkan adapter saat bekerja dengan tipe yang sesuai.

Apakah Moshi mendukung Kotlin Multiplatform?

Ya, Moshi mendukung Kotlin Multiplatform mulai versi 1.13.0. Ini menjadikannya satu-satunya solusi JSON populer untuk proyek KMP, memungkinkan penggunaan kode serialisasi umum di semua platform target.

Kesimpulan

  • Moshi — pustaka JSON modern dari Square dengan generasi kode alih-alih refleksi
  • @JsonClass — anotasi untuk generasi adapter, memberikan kecepatan kode yang ditulis tangan
  • @Json — konfigurasi kunci JSON, @Transient — pengecualian bidang dari serialisasi
  • @ToJson dan @FromJson — API sederhana untuk adapter kustom tipe apa pun
  • Null safety — Moshi memperhitungkan anotasi Kotlin dan melempar pengecualian saat ketidakcocokan
  • Kinerja — 2-5 kali lebih cepat dari Gson pada operasi serialisasi dan deserialisasi
  • Kotlin Multiplatform — dukungan KMP untuk kode serialisasi universal

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga