Moshi: əsas anlayışlar, JSON Kotlin kitabxanası və necə işləyir

Müəllif: IT Sectr Dərc olunub: 2026-03-15 Oxuma vaxtı: 8 dəq

Moshi Square tərəfindən yaradılmış, xüsusilə Kotlin və Android üçün Gson məhdudiyyətləri nəzərə alınaraq hazırlanmış müasir JSON kitabxanasıdır. O, Kotlin-in null-təhlükəsizliyi ilə tam uyğundur, kompilasiya mərhələsində kod yaradır və reflektasiyadan istifadə etmir, bu da performansı və etibarlılığı artırır. Square Moshi, 2024 məlumatlarına görə, Moshi proqnozlaşdırıla bilən serializasiya təmin edir və istənilən verilən tipi üçün fərdi adapterləri dəstəkləyir.

Əsas məqamlar

  • Moshi — Square-dən Kotlin və Android üçün reflektasiyasız JSON kitabxanası
  • Kotlin adapteri — data class, default dəyərlər və null safety üçün daxili dəstək
  • @Json — sahə adını konfiqurasiya etmək və xassələri görməməzlikdən gəlmək üçün annotasiya
  • Adapterlər — @ToJson və @FromJson vasitəsilə fərdi serializasiya məntiqi
  • Kod generasiyası — Moshi kapt və ya KSP vasitəsilə kompilasiya mərhələsində adapterlər yaradır

Moshi nədir

Moshi — Square (OkHttp və Retrofit müəllifləri) tərəfindən yaradılmış JVM, Android və Kotlin Multiplatform üçün JSON kitabxanasıdır. Gson-dan fərqli olaraq, Moshi reflektasiyaya güvənmir — adapterlər @JsonClass(generateAdapter = true) annotasiyası vasitəsilə kompilasiya mərhələsində yaradılır. Bu, Moshi-ni Kotlin-spesifik konstruksiyalarla işləyərkən daha sürətli, təhlükəsiz və proqnozlaşdırıla bilən edir.

Fəlsəfə və üstünlüklər

Moshi-nin sələflərindən əsas fərqi reflektasiyadan imtina etməsidir. Reflektasiya Gson-a heç bir hazırlıq olmadan istənilən siniflə işləməyə imkan verir, lakin bunun əvəzində yavaş inisializasiya, kompilator tərəfindən optimallaşdırmanın mümkünsüzlüyü və icra zamanı xəta riski ödənilir. Moshi kod generasiyası üçün siniflərin açıq şəkildə göstərilməsini tələb edir, lakin əvəzində əl ilə yazılmış kodun sürətini və kompilasiya mərhələsində tam tip təhlükəsizliyini verir.

kotlin
// Moshi-ni build.gradle-ə qoşmaq
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 generasiyası ilə sadə model
@JsonClass(generateAdapter = true)
data class User(
    @Json(name = "user_id")
    val id: Int,
    val name: String,
    val email: String,
    val avatar: String? = null
)

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

Qoşulma və quraşdırma

Moshi ilə işə başlamaq üçün build.gradle-ə asılılıqlar əlavə etmək və modelləri annotasiya etmək lazımdır. Moshi.Builder giriş nöqtəsi kimi xidmət edir: onun vasitəsilə standart tiplər üçün daxili adapterlər, fərdi adapterlər əlavə edilir və kitabxananın davranışı konfiqurasiya edilir. Moshi Date, Enum, Collection və Map üçün adapterləri qutudan çıxan kimi dəstəkləyir, lakin Kotlin sinifləri üçün moshi-kotlin modulu tələb olunur. Gson-dan fərqli olaraq, Moshi Kotlin sinifləri üçün standart olaraq reflektasiyadan istifadə etmir — bunun üçün KotlinJsonAdapterFactory qoşulur, o, kod generasiyası tətbiq edilmədikdə və ya sinif @JsonClass ilə annotasiya edilmədikdə ehtiyat variant kimi xidmət edir. Bu yanaşma təmin edir ki, tərtibatçı hər bir konkret sinif üçün kod generasiyasının performansı ilə reflektasiyanın çevikliyi arasında açıq şəkildə seçim edir.

Moshi yaratmaq və adapterlər əlavə etmək

Builder vasitəsilə Moshi qurulduqdan sonra tərtibatçı Moshi nümunəsini alır və lazımi sinif üçün adapter tələb edir. JsonAdapter — toJson() vasitəsilə serializasiya və fromJson() vasitəsilə deserializasiya yerinə yetirən mərkəzi obyektdir. Moshi sinif @JsonClass(generateAdapter = true) ilə annotasiya edilibsə avtomatik olaraq yaradılmış adapterdən istifadə edir, əks halda ehtiyat variant kimi refleksiv KotlinJsonAdapterFactory tətbiq edir. Bu yanaşma kod generasiyasının sürətini istənilən miqyaslı və mürəkkəblik səviyyəli layihələr üçün refleksiv mexanizmin çevikliyi ilə birləşdirir. Moshi həm kiçik tətbiqlər, həm də yüzlərlə verilən modeli olan böyük korporativ layihələr üçün mükəmməl uyğundur.

kotlin
// Moshi-ni KotlinJsonAdapterFactory ilə konfiqurasiya etmək
val moshi = Moshi.Builder()
    .add(KotlinJsonAdapterFactory())
    .add(LocalDateAdapter())
    .build()

// Adapterin istifadəsi
val adapter = moshi.adapter(User::class.java)

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

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

// Siyahı ilə iş
val listAdapter = moshi.adapter(
    Types.newParameterizedType(
        List::class.java,
        User::class.java
    )
)

Annotasiyalar və adapterlər

Moshi serializasiyanı konfiqurasiya etmək və fərdi tipləri dəstəkləmək üçün annotasiyalardan istifadə edir. @Json(name = "...") sahə üçün JSON açarını təyin edir. @Transient sahəni serializasiyadan xaric edir. @JsonClass(generateAdapter = true) kod generasiyasını aktivləşdirir. Fərdi məntiq üçün Moshi ayrıca adapter sinfində yerləşdirilə bilən @ToJson və @FromJson annotasiyalarını təqdim edir.

@Json və fərdi adapterlər

@Json annotasiyası Gson-un @SerializedName-ni əvəz edir və eyni şəkildə işləyir: kotlinName sahəsi JSON açarı „kotlin_name" ilə əlaqələndirilir. Moshi-nin standart olaraq serializasiya edə bilmədiyi tiplər üçün (məsələn, LocalDate) tərtibatçı @ToJson və @FromJson metodları olan sinif yaradır. Adapterlər Moshi.Builder.add() vasitəsilə qeydiyyatdan keçirilir və qlobal olaraq və ya konkret tipə tətbiq edilir. Moshi sealed class və diskriminatorun açıq göstəricisi ilə @JsonClass vasitəsilə polimorf serializasiyanı dəstəkləyir, bu da sahələrin əl ilə yoxlanılmasına ehtiyac olmadan JSON-da tip iyerarxiyaları ilə işləməyə imkan verir. Deserializasiya zamanı Moshi standart olaraq JSON-da naməlum açarları görməməzlikdən gəlir, bu da server tərəfdə yeni sahələr əlavə edilərkən müştəri kodunu dəyişmədən geriyə uyğunluğu təmin edir. Debug üçün failOnUnknown vasitəsilə sərt rejimi aktivləşdirmək olar, o, naməlum açarlar aşkar edildikdə istisna atır.

kotlin
// LocalDate üçün fərdi adapter
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 annotasiyaları ilə 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
)

// Adapterin qeydiyyatı
val moshi = Moshi.Builder()
    .add(LocalDateAdapter())
    .add(KotlinJsonAdapterFactory())
    .build()

Moshi vs Gson

Moshi və Gson müqayisəsi Android layihəsi üçün JSON kitabxanası seçərkən tez-tez verilən sualdır. Moshi kod generasiyası, null-təhlükəsizliyi və sürəti sayəsində müasir Kotlin inkişafında qalib gəlir. Gson Java layihələri, legacy-kod və minimal konfiqurasiyanın vacib olduğu ssenarilər üçün aktual qalır. Fərq böyük verilən həcmlərində və mürəkkəb modellərdə nəzərə çarpır.

Performans və təhlükəsizlik

Performans testləri göstərir ki, kod generasiyası ilə Moshi serializasiya və deserializasiya əməliyyatlarında Gson-dan 2-5 dəfə sürətli işləyir. Moshi-nin əsas üstünlüyü Kotlin null-təhlükəsizliyinin düzgün işlənməsidir: JSON-da sahə yoxdursa və modeldə o, default dəyər olmadan non-null elan edilibsə, Moshi deserializasiya mərhələsində istisna atır, gizli səhvlərin qarşısını alır.

XüsusiyyətGsonMoshi
Mexanizmreflektasiyakod generasiyası / reflektasiya
Null safetynəzərə almırtam Kotlin dəstəyi
Sürətortayüksək
Default dəyərlərdəstəkləmirdəstəkləyir
Kotlin Multiplatformxeyrbəli
Kitabxana ölçüsü~240 Kb~150 Kb

Moshi və Gson arasında seçim layihənin kontekstindən asılıdır. Kotlin-də yeni layihələr tip təhlükəsizliyi və performans sayəsində Moshi-dən qazanır. Gson Java kodunu dəstəkləmək, dinamik JSON strukturları və ya qoşulmanın sadəliyinin sürətdən daha vacib olduğu hallar üçün ağlabatan seçim olaraq qalır. Kotlin Multiplatform üçün Moshi bu platformanı dəstəkləyən iki variantdan yeganəsidir.

Gson-dan Moshi-yə miqrasiya zamanı əsas dəyişikliklər annotasiyalara və adapterlərə aiddir. Gson-un @SerializedName-i @Json(name = "...") ilə, fərdi JsonSerializer/JsonDeserializer isə @ToJson/@FromJson cütlüyü ilə əvəz olunur. Default dəyərləri və nullable sahələri olan modellər üçün Moshi daha proqnozlaşdırıla bilən davranır: JSON-da default dəyər olmadan non-null sahə yoxdursa, Moshi JsonDataException atır, gizli NPE-nin qarşısını alır. Retrofit ilə MoshiConverterFactory vasitəsilə inteqrasiya bir asılılıqla əlavə edilir və şəbəkə təbəqəsinin arxitekturasını dəyişməyi tələb etmir. ProGuard və ya R8 vasitəsilə obfuskasiya üçün @JsonClass annotasiyalı siniflərin və yaradılmış adapterlərin saxlanması qaydalarını əlavə etmək lazımdır, əks halda serializasiya release quruluşunda sınar. Ümumilikdə, Gson-dan Moshi-yə miqrasiya performansın və tip təhlükəsizliyinin vacib olduğu yeni Kotlin layihələrində əsaslandırılmışdır.

kotlin
// Serializasiya müqayisəsi: Gson vs Moshi
data class Sample(
    val name: String,
    val count: Int,
    val tags: List<String> = listOf()
)

// Gson: reflektasiya vasitəsilə işləyir
val gson = Gson()
val fromGson = gson.fromJson("""{"name":"test"}""",
    Sample::class.java)
// count = 0 (default), lakin null-təhlükəsizlik yoxlanılmır

// Moshi: adapter tələb edir, null-təhlükəsizlik açıqdır
@JsonClass(generateAdapter = true)
data class SampleMoshi(
    val name: String,
    val count: Int,
    val tags: List<String> = listOf()
)

Tez-tez verilən suallar

Android-də Moshi nədir?

Moshi — Square-dən Kotlin və Android üçün reflektasiya yerinə kod generasiyası istifadə edən JSON kitabxanasıdır. O, yüksək performans, Kotlin null-təhlükəsizliyinin düzgün işlənməsi və Kotlin Multiplatform ilə uyğunluq təmin edir.

Moshi Gson-dan nə ilə yaxşıdır?

Moshi Gson-u sürətdə (kod generasiyası sayəsində 2-5 dəfə sürətli), təhlükəsizlikdə (Kotlin null-annotasiyalarını nəzərə alır) və ölçüdə (~90 Kb daha kiçik) üstələyir. Moshi həmçinin Kotlin Multiplatform və data class-da default dəyərləri dəstəkləyir.

Moshi-də @JsonClass annotasiyası necə işləyir?

@JsonClass(generateAdapter = true) Moshi-yə kompilasiya mərhələsində bu sinif üçün adapter yaratmağı göstərir. Yaradılmış adapter serializasiyanı birbaşa, reflektasiya olmadan yerinə yetirir, bu da maksimum performans verir.

Moshi üçün fərdi adapteri necə yaratmaq olar?

@ToJson (serializasiya) və @FromJson (deserializasiya) annotasiyalı metodları olan sinif yaradın. Nümunəni Moshi.Builder.add() vasitəsilə qeydiyyatdan keçirin. Moshi müvafiq tiplə işləyərkən avtomatik olaraq adapteri tapıb tətbiq edəcək.

Moshi Kotlin Multiplatform-u dəstəkləyirmi?

Bəli, Moshi 1.13.0 versiyasından etibarən Kotlin Multiplatform-u dəstəkləyir. Bu, onu KMP layihələri üçün yeganə məşhur JSON həlli edir və bütün hədəf platformalarda ümumi serializasiya kodundan istifadə etməyə imkan verir.

Nəticə

  • Moshi — Square-dən reflektasiya yerinə kod generasiyası ilə müasir JSON kitabxanası
  • @JsonClass — adapter generasiyası üçün annotasiya, əl ilə yazılmış kod sürətini təmin edir
  • @Json — JSON açarlarının konfiqurasiyası, @Transient — sahələrin serializasiyadan xaric edilməsi
  • @ToJson və @FromJson — istənilən tiplər üçün fərdi adapterlər üçün sadə API
  • Null safety — Moshi Kotlin annotasiyalarını nəzərə alır və uyğunsuzluqda istisna atır
  • Performans — serializasiya və deserializasiya əməliyyatlarında Gson-dan 2-5 dəfə sürətli
  • Kotlin Multiplatform — universal serializasiya kodu üçün KMP dəstəyi

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun