Moshi: temel kavramlar, Kotlin için JSON kütüphanesi ve nasıl çalışır

Yazar: IT Sectr Yayınlanma: 2026-03-15 Okuma süresi: 8 dk

Moshi, Square tarafından Gson’ın sınırlamaları dikkate alınarak özellikle Kotlin ve Android için oluşturulmuş modern bir JSON kütüphanesidir. Kotlin’in null güvenliğiyle tam uyumludur, derleme zamanında kod üretir ve yansıma kullanmaz, bu da performansı ve güvenilirliği artırır. Square Moshi, 2024’e göre, Moshi öngörülebilir serileştirme sağlar ve her tür veri için özel adaptörleri destekler.

Ana Noktalar

  • Moshi — Square’in Kotlin ve Android için yansımasız JSON kütüphanesi
  • Kotlin adaptörü — data class, varsayılan değerler ve null güvenliği için yerleşik destek
  • @Json — alan adını yapılandırmak ve özellikleri yok saymak için anotasyon
  • Adaptörler — @ToJson ve @FromJson ile özel serileştirme mantığı
  • Kod üretimi — Moshi, kapt veya KSP aracılığıyla derleme zamanında adaptörler üretir

Moshi Nedir

Moshi, Square (OkHttp ve Retrofit’in yazarları) tarafından oluşturulmuş, JVM, Android ve Kotlin Multiplatform için bir JSON kütüphanesidir. Gson’ın aksine Moshi yansımaya dayanmaz — adaptörler @JsonClass(generateAdapter = true) anotasyonu aracılığıyla derleme zamanında üretilir. Bu, Moshi’yi Kotlin’e özgü yapılarla çalışırken daha hızlı, güvenli ve öngörülebilir kılar.

Felsefe ve Avantajlar

Moshi’nin seleflerinden temel farkı, yansımayı reddetmesidir. Yansıma, Gson’ın hazırlık yapmadan herhangi bir sınıfla çalışmasına izin verir, ancak bunun bedeli yavaş başlatma, derleyici tarafından optimize edilememe ve çalışma zamanı hataları riskidir. Moshi, kod üretimi için sınıfların açıkça bildirilmesini gerektirir, ancak karşılığında el yazımı kodun hızını ve derleme zamanında tam tip güvenliğini sunar.

kotlin
// Moshi’yi build.gradle’a ekleyin
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"
}

// Kod üretimiyle basit model
@JsonClass(generateAdapter = true)
data class User(
    @Json(name = "user_id")
    val id: Int,
    val name: String,
    val email: String,
    val avatar: String? = null
)

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

Kurulum ve Yapılandırma

Moshi ile çalışmaya başlamak için build.gradle’a bağımlılıklar eklemek ve modelleri anotasyonlamak gerekir. Moshi.Builder giriş noktası olarak hizmet eder: bunun aracılığıyla standart türler için yerleşik adaptörler, özel adaptörler eklenir ve kütüphanenin davranışı yapılandırılır. Moshi, Date, Enum, Collection ve Map için adaptörleri kutudan çıkar çıkmaz destekler, ancak Kotlin sınıfları moshi-kotlin modülünü gerektirir. Gson’ın aksine Moshi, varsayılan olarak Kotlin sınıfları için yansıma kullanmaz — bunun için KotlinJsonAdapterFactory bağlanır ve kod üretimi kullanılmadığında veya sınıf @JsonClass ile anotasyonlanmadığında yedek seçenek olarak işlev görür. Bu yaklaşım, geliştiricinin her bir sınıf için kod üretiminin performansı ile yansımanın esnekliği arasında açıkça seçim yapmasını sağlar.

Moshi Oluşturma ve Adaptör Ekleme

Builder aracılığıyla Moshi oluşturulduktan sonra, geliştirici bir Moshi örneği alır ve istenen sınıf için bir adaptör talep eder. JsonAdapter, toJson() aracılığıyla serileştirme ve fromJson() aracılığıyla serileştirmeden çözme işlemlerini gerçekleştiren merkezi nesnedir. Sınıf @JsonClass(generateAdapter = true) ile anotasyonlanmışsa Moshi otomatik olarak üretilen adaptörü kullanır, aksi takdirde yedek olarak yansıtıcı KotlinJsonAdapterFactory’yi uygular. Bu yaklaşım, her ölçek ve karmaşıklıktaki projeler için kod üretiminin hızını yansıtıcı mekanizmanın esnekliğiyle birleştirir. Moshi, küçük uygulamalardan yüzlerce veri modeline sahip büyük kurumsal projelere kadar uygundur.

kotlin
// Moshi’yi KotlinJsonAdapterFactory ile yapılandırın
val moshi = Moshi.Builder()
    .add(KotlinJsonAdapterFactory())
    .add(LocalDateAdapter())
    .build()

// Adaptörü kullanma
val adapter = moshi.adapter(User::class.java)

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

// Serileştirmeden çözme
val jsonString = """{"user_id":2,"name":"Bob","email":"bob@test.com"}"""
val parsedUser = adapter.fromJson(jsonString)

// Listelerle çalışma
val listAdapter = moshi.adapter(
    Types.newParameterizedType(
        List::class.java,
        User::class.java
    )
)

Anotasyonlar ve Adaptörler

Moshi, serileştirmeyi yapılandırmak ve özel türleri desteklemek için anotasyonlar kullanır. @Json(name = "...") bir alan için JSON anahtarını belirler. @Transient bir alanı serileştirmenin dışında bırakır. @JsonClass(generateAdapter = true) kod üretimini etkinleştirir. Özel mantık için Moshi, ayrı bir adaptör sınıfına yerleştirilebilen @ToJson ve @FromJson anotasyonlarını sağlar.

@Json ve Özel Adaptörler

@Json anotasyonu, Gson’ın @SerializedName’inin yerini alır ve benzer şekilde çalışır: kotlinName alanı "kotlin_name" JSON anahtarına bağlanır. Moshi’nin varsayılan olarak serileştiremediği türler için (örn. LocalDate), geliştirici @ToJson ve @FromJson yöntemlerine sahip bir sınıf oluşturur. Adaptörler Moshi.Builder.add() aracılığıyla kaydedilir ve küresel olarak veya belirli bir türe uygulanır. Moshi, ayrılmış sınıfları ve açık bir ayırıcıyla @JsonClass aracılığıyla çok biçimli serileştirmeyi destekler ve bu sayede manuel alan denetimi olmadan JSON’da tür hiyerarşileriyle çalışılmasına olanak tanır. Serileştirmeden çözme sırasında Moshi, varsayılan olarak bilinmeyen JSON anahtarlarını yok sayar ve istemci kodunu değiştirmeden sunucu tarafına yeni alanlar eklerken geriye dönük uyumluluk sağlar. Hata ayıklama için, failOnUnknown aracılığıyla katı mod etkinleştirilebilir ve bilinmeyen anahtarlar bulunduğunda bir istisna fırlatılır.

kotlin
// LocalDate için özel adaptör
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)
    }
}

// Moshi anotasyonlarıyla model
@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
)

// Adaptörü kaydetme
val moshi = Moshi.Builder()
    .add(LocalDateAdapter())
    .add(KotlinJsonAdapterFactory())
    .build()

Moshi vs Gson

Moshi ve Gson’ı karşılaştırmak, bir Android projesi için JSON kütüphanesi seçerken sık sorulan bir sorudur. Moshi, kod üretimi, null güvenliği ve hız sayesinde modern Kotlin geliştirmede öne çıkar. Gson, Java projeleri, eski kod ve minimum yapılandırmanın önemli olduğu senaryolar için geçerliliğini korur. Fark, büyük veri hacimleri ve karmaşık modellerde belirginleşir.

Performans ve Güvenlik

Performans testleri, kod üretimiyle Moshi’nin serileştirme ve serileştirmeden çözme işlemlerinde Gson’dan 2–5 kat daha hızlı olduğunu gösteriyor. Moshi’nin temel avantajı, Kotlin null güvenliğini doğru şekilde işlemesidir: JSON’da bir alan eksikse ve model bunu varsayılan değer olmadan null değil olarak bildiriyorsa, Moshi serileştirmeden çözme sırasında bir istisna fırlatarak gizli hataları önler.

ÖzellikGsonMoshi
Mekanizmayansımakod üretimi / yansıma
Null güvenliğidikkate almaztam Kotlin desteği
Hızortayüksek
Varsayılan değerlerdesteklemezdestekler
Kotlin Multiplatformhayırevet
Kütüphane boyutu~240 Kb~150 Kb

Moshi ve Gson arasındaki seçim proje bağlamına bağlıdır. Kotlin’deki yeni projeler, tip güvenliği ve performans sayesinde Moshi’den yararlanır. Gson, Java kodunu desteklemek, dinamik JSON yapıları veya yapılandırma basitliğinin hızdan daha önemli olduğu durumlar için makul bir seçim olmaya devam ediyor. Kotlin Multiplatform için Moshi, bu platformu destekleyen iki seçenekten tek olanıdır.

Gson’dan Moshi’ye geçişte ana değişiklikler anotasyonlar ve adaptörlerle ilgilidir. Gson’un @SerializedName’i @Json(name = "...") ile değiştirilir ve özel JsonSerializer/JsonDeserializer, @ToJson/@FromJson çiftiyle değiştirilir. Varsayılan değerler ve nullable alanlar içeren modeller için Moshi daha öngörülebilir davranır: JSON’da varsayılanı olmayan bir null değil alan eksikse, Moshi JsonDataException fırlatarak gizli NPE’leri önler. MoshiConverterFactory aracılığıyla Retrofit ile entegrasyon, tek bir bağımlılıkla eklenir ve ağ katmanı mimarisinin değiştirilmesini gerektirmez. ProGuard veya R8 aracılığıyla karartma için, @JsonClass ile anotasyonlanmış sınıfları ve üretilen adaptörleri korumak üzere kurallar eklenmelidir, aksi takdirde sürüm yapısında serileştirme bozulur. Genel olarak, Gson’dan Moshi’ye geçiş, performans ve tip güvenliğinin önemli olduğu yeni Kotlin projelerinde haklıdır.

kotlin
// Serileştirme karşılaştırması: Gson vs Moshi
data class Sample(
    val name: String,
    val count: Int,
    val tags: List<String> = listOf()
)

// Gson: yansıma yoluyla çalışır
val gson = Gson()
val fromGson = gson.fromJson("""{"name":"test"}""",
    Sample::class.java)
// count = 0 (varsayılan), ancak null güvenliği kontrol edilmez

// Moshi: adaptör gerektirir, null güvenliği açıktır
@JsonClass(generateAdapter = true)
data class SampleMoshi(
    val name: String,
    val count: Int,
    val tags: List<String> = listOf()
)

Sıkça Sorulan Sorular

Android’de Moshi nedir?

Moshi, yansıma yerine kod üretimi kullanan Square’in Kotlin ve Android için bir JSON kütüphanesidir. Yüksek performans, Kotlin null güvenliğinin doğru işlenmesi ve Kotlin Multiplatform ile uyumluluk sağlar.

Moshi Gson’dan nasıl daha iyidir?

Moshi, hız (kod üretimi sayesinde 2–5 kat daha hızlı), güvenlik (Kotlin null anotasyonlarını dikkate alır) ve boyut (~90 Kb daha küçük) açısından Gson’u geride bırakır. Moshi ayrıca Kotlin Multiplatform’u ve data class’larda varsayılan değerleri destekler.

Moshi’de @JsonClass anotasyonu nasıl çalışır?

@JsonClass(generateAdapter = true), Moshi’ye belirtilen sınıf için derleme zamanında bir adaptör oluşturmasını söyler. Oluşturulan adaptör, yansıma olmadan doğrudan serileştirme yaparak maksimum performans sağlar.

Özel bir Moshi adaptörü nasıl oluşturulur?

@ToJson (serileştirme) ve @FromJson (serileştirmeden çözme) ile anotasyonlanmış yöntemlere sahip bir sınıf oluşturun. Örneği Moshi.Builder.add() aracılığıyla kaydedin. Moshi, ilgili türle çalışırken adaptörü otomatik olarak bulur ve uygular.

Moshi Kotlin Multiplatform’u destekliyor mu?

Evet, Moshi sürüm 1.13.0’dan itibaren Kotlin Multiplatform’u desteklemektedir. Bu, onu KMP projeleri için tek popüler JSON çözümü yapar ve tüm hedef platformlarda ortak serileştirme kodu kullanılmasına olanak tanır.

Özet

  • Moshi — yansıma yerine kod üretimiyle Square’in modern JSON kütüphanesi
  • @JsonClass — el yazımı kod hızı sunan adaptör üretimi anotasyonu
  • @Json — JSON anahtar yapılandırması, @Transient — alanları serileştirmeden hariç tutma
  • @ToJson ve @FromJson — her tür için özel adaptörlerin basit API’si
  • Null güvenliği — Moshi Kotlin anotasyonlarını dikkate alır ve uyuşmazlıkta istisna fırlatır
  • Performans — serileştirme ve serileştirmeden çözme işlemlerinde Gson’dan 2–5 kat daha hızlı
  • Kotlin Multiplatform — evrensel serileştirme kodu için KMP desteği

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun