Moshi: klíčové pojmy, JSON knihovna Kotlin a jak funguje

Autor: IT Sectr Publikováno: 2026-03-15 Doba čtení: 8 min

Moshi je moderní JSON knihovna od Square, vytvořená speciálně pro Kotlin a Android s ohledem na omezení Gson. Je plně kompatibilní s null-bezpečností Kotlin, generuje kód ve fázi kompilace a nepoužívá reflexi, což zvyšuje výkon a spolehlivost. Podle údajů Square Moshi, 2024, Moshi poskytuje předvídatelnou serializaci a podporuje vlastní adaptéry pro všechny typy dat.

Hlavní body

  • Moshi — JSON knihovna od Square pro Kotlin a Android bez reflexe
  • Kotlin adaptér — vestavěná podpora pro data class, výchozí hodnoty a null safety
  • @Json — anotace pro konfiguraci názvu pole a ignorování vlastností
  • Adaptéry — vlastní logika serializace pomocí @ToJson a @FromJson
  • Generování kódu — Moshi generuje adaptéry ve fázi kompilace pomocí kapt nebo KSP

Co je Moshi

Moshi je JSON knihovna pro JVM, Android a Kotlin Multiplatform, vytvořená společností Square (autory OkHttp a Retrofit). Na rozdíl od Gson, Moshi nespoléhá na reflexi — adaptéry jsou generovány ve fázi kompilace pomocí anotace @JsonClass(generateAdapter = true). Díky tomu je Moshi rychlejší, bezpečnější a předvídatelnější při práci s konstrukcemi specifickými pro Kotlin.

Filozofie a výhody

Hlavním rozdílem Moshi oproti předchůdcům je opuštění reflexe. Reflexe umožňuje Gson pracovat s jakoukoli třídou bez přípravy, ale za cenu pomalé inicializace, nemožnosti optimalizace kompilátorem a rizika chyb za běhu. Moshi vyžaduje explicitní uvedení tříd pro generování kódu, ale na oplátku poskytuje rychlost ručně psaného kódu a úplnou typovou bezpečnost ve fázi kompilace.

kotlin
// Připojení Moshi v 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"
}

// Jednoduchý model s generováním kódu
@JsonClass(generateAdapter = true)
data class User(
    @Json(name = "user_id")
    val id: Int,
    val name: String,
    val email: String,
    val avatar: String? = null
)

// Použití
val moshi = Moshi.Builder()
    .build()
val jsonAdapter = moshi.adapter(User::class.java)

Připojení a konfigurace

Pro zahájení práce s Moshi je třeba přidat závislosti v build.gradle a anotovat modely. Moshi.Builder slouží jako vstupní bod: prostřednictvím něj se přidávají vestavěné adaptéry pro standardní typy, vlastní adaptéry a konfiguruje se chování knihovny. Moshi podporuje adaptéry pro Date, Enum, Collection a Map hned po vybalení, ale pro třídy Kotlin je vyžadován modul moshi-kotlin. Na rozdíl od Gson, Moshi standardně nepoužívá reflexi pro třídy Kotlin — k tomu se připojuje KotlinJsonAdapterFactory, který slouží jako záložní volba, když se negeneruje kód nebo třída není anotována @JsonClass. Tento přístup zaručuje, že vývojář explicitně volí mezi výkonem generování kódu a flexibilitou reflexe pro každou konkrétní třídu.

Vytvoření Moshi a přidání adaptérů

Po sestavení Moshi pomocí Builderu získá vývojář instanci Moshi a požádá o adaptér pro požadovanou třídu. JsonAdapter je centrální objekt, který provádí serializaci pomocí toJson() a deserializaci pomocí fromJson(). Moshi automaticky používá vygenerovaný adaptér, pokud je třída anotována @JsonClass(generateAdapter = true), jinak použije reflexivní KotlinJsonAdapterFactory jako záložní volbu. Tento přístup kombinuje rychlost generování kódu s flexibilitou reflexivního mechanismu pro projekty jakékoli velikosti a úrovně složitosti. Moshi je vhodný jak pro malé aplikace, tak pro velké korporátní projekty se stovkami datových modelů.

kotlin
// Konfigurace Moshi s KotlinJsonAdapterFactory
val moshi = Moshi.Builder()
    .add(KotlinJsonAdapterFactory())
    .add(LocalDateAdapter())
    .build()

// Použití adaptéru
val adapter = moshi.adapter(User::class.java)

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

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

// Práce se seznamem
val listAdapter = moshi.adapter(
    Types.newParameterizedType(
        List::class.java,
        User::class.java
    )
)

Anotace a adaptéry

Moshi používá anotace pro konfiguraci serializace a podporu vlastních typů. @Json(name = "...") nastavuje JSON klíč pro pole. @Transient vylučuje pole ze serializace. @JsonClass(generateAdapter = true) zapíná generování kódu. Pro vlastní logiku Moshi poskytuje anotace @ToJson a @FromJson, které lze umístit do samostatné třídy adaptéru.

@Json a vlastní adaptéry

Anotace @Json nahrazuje Gsonovský @SerializedName a funguje podobně: pole kotlinName je propojeno s JSON klíčem „kotlin_name“. Pro typy, které Moshi nedokáže serializovat standardně (např. LocalDate), vytvoří vývojář třídu s metodami @ToJson a @FromJson. Adaptéry se registrují pomocí Moshi.Builder.add() a aplikují se globálně nebo na konkrétní typ. Moshi podporuje sealed class a polymorfní serializaci pomocí @JsonClass s explicitním uvedením diskriminátoru, což umožňuje práci s hierarchiemi typů v JSON bez ruční kontroly polí. Při deserializaci Moshi standardně ignoruje neznámé klíče v JSON, což zajišťuje zpětnou kompatibilitu při přidávání nových polí na straně serveru bez změny kódu klienta. Pro ladění lze zapnout přísný režim pomocí failOnUnknown, který vyvolá výjimku při detekci neznámých klíčů.

kotlin
// Vlastní adaptér pro 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 s anotacemi 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
)

// Registrace adaptéru
val moshi = Moshi.Builder()
    .add(LocalDateAdapter())
    .add(KotlinJsonAdapterFactory())
    .build()

Moshi vs Gson

Srovnání Moshi a Gson je častá otázka při výběru JSON knihovny pro Android projekt. Moshi vítězí v moderním vývoji Kotlin díky generování kódu, null-bezpečnosti a rychlosti. Gson zůstává relevantní pro Java projekty, legacy kód a scénáře, kde je důležitá minimální konfigurace. Rozdíl je patrný při velkých objemech dat a složitých modelech.

Výkon a bezpečnost

Výkonnostní testy ukazují, že Moshi s generováním kódu pracuje 2-5krát rychleji než Gson při serializaci a deserializaci. Klíčovou výhodou Moshi je správné zpracování null-bezpečnosti Kotlin: pokud pole chybí v JSON a v modelu je deklarováno jako non-null bez výchozí hodnoty, Moshi vyvolá výjimku ve fázi deserializace, čímž předchází skrytým chybám.

VlastnostGsonMoshi
Mechanismusreflexegenerování kódu / reflexe
Null safetynebere v úvahuplná podpora Kotlin
Rychloststřednívysoká
Výchozí hodnotynepodporujepodporuje
Kotlin Multiplatformneano
Velikost knihovny~240 Kb~150 Kb

Volba mezi Moshi a Gson závisí na kontextu projektu. Nové projekty na Kotlin těží z Moshi díky typové bezpečnosti a výkonu. Gson zůstává rozumnou volbou pro podporu Java kódu, dynamických JSON struktur nebo když je jednoduchost připojení důležitější než rychlost. Pro Kotlin Multiplatform je Moshi jediným z obou variant, který tuto platformu podporuje.

Při migraci z Gson na Moshi se hlavní změny týkají anotací a adaptérů. Gsonovský @SerializedName se nahrazuje @Json(name = "...") a vlastní JsonSerializer/JsonDeserializer — dvojicí @ToJson/@FromJson. Pro modely s výchozími hodnotami a nullable poli se Moshi chová předvídatelněji: pokud v JSON chybí non-null pole bez výchozí hodnoty, Moshi vyvolá JsonDataException, čímž předchází skrytým NPE. Integrace s Retrofit přes MoshiConverterFactory se přidá jednou závislostí a nevyžaduje změnu architektury síťové vrstvy. Pro obfuskaci přes ProGuard nebo R8 je třeba přidat pravidla pro zachování tříd anotovaných @JsonClass a generovaných adaptérů, jinak se serializace rozbije v release verzi. Celkově je migrace z Gson na Moshi opodstatněná v nových Kotlin projektech, kde je důležitý výkon a typová bezpečnost.

kotlin
// Porovnání serializace: Gson vs Moshi
data class Sample(
    val name: String,
    val count: Int,
    val tags: List<String> = listOf()
)

// Gson: funguje přes reflexi
val gson = Gson()
val fromGson = gson.fromJson("""{"name":"test"}""",
    Sample::class.java)
// count = 0 (default), ale null-bezpečnost není kontrolována

// Moshi: vyžaduje adaptér, null-bezpečnost je explicitní
@JsonClass(generateAdapter = true)
data class SampleMoshi(
    val name: String,
    val count: Int,
    val tags: List<String> = listOf()
)

Často kladené otázky

Co je Moshi v Androidu?

Moshi je JSON knihovna od Square pro Kotlin a Android, která používá generování kódu místo reflexe. Poskytuje vysoký výkon, správné zpracování null-bezpečnosti Kotlin a kompatibilitu s Kotlin Multiplatform.

Čím je Moshi lepší než Gson?

Moshi překonává Gson v rychlosti (2-5krát rychlejší díky generování kódu), bezpečnosti (bere v úvahu null anotace Kotlin) a velikosti (o ~90 Kb menší). Moshi také podporuje Kotlin Multiplatform a výchozí hodnoty v data class.

Jak funguje anotace @JsonClass v Moshi?

@JsonClass(generateAdapter = true) přikazuje Moshi vygenerovat adaptér pro tuto třídu ve fázi kompilace. Vygenerovaný adaptér provádí serializaci přímo, bez reflexe, což poskytuje maximální výkon.

Jak vytvořit vlastní Moshi adaptér?

Vytvořte třídu s metodami anotovanými @ToJson (serializace) a @FromJson (deserializace). Zaregistrujte instanci pomocí Moshi.Builder.add(). Moshi automaticky najde a použije adaptér při práci s odpovídajícím typem.

Podporuje Moshi Kotlin Multiplatform?

Ano, Moshi podporuje Kotlin Multiplatform od verze 1.13.0. To z něj dělá jediné populární JSON řešení pro KMP projekty, umožňující použití společného serializačního kódu na všech cílových platformách.

Shrnutí

  • Moshi — moderní JSON knihovna od Square s generováním kódu místo reflexe
  • @JsonClass — anotace pro generování adaptéru, zajišťující rychlost ručně psaného kódu
  • @Json — konfigurace JSON klíčů, @Transient — vyloučení polí z serializace
  • @ToJson a @FromJson — jednoduché API pro vlastní adaptéry libovolných typů
  • Null safety — Moshi bere v úvahu Kotlin anotace a vyvolá výjimku při neshodě
  • Výkon — 2-5krát rychlejší než Gson při serializaci a deserializaci
  • Kotlin Multiplatform — podpora KMP pro univerzální serializační kód

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také