Moshi: concetti chiave, libreria JSON per Kotlin e come funziona

Autore: IT Sectr Pubblicato: 2026-03-15 Tempo di lettura: 8 min

Moshi è una libreria JSON moderna di Square, creata specificamente per Kotlin e Android tenendo conto dei limiti di Gson. È completamente compatibile con la sicurezza nulla di Kotlin, genera codice in fase di compilazione e non utilizza la riflessione, migliorando le prestazioni e l'affidabilità. Secondo Square Moshi, 2024, Moshi fornisce una serializzazione prevedibile e supporta adattatori personalizzati per qualsiasi tipo di dato.

Punti chiave

  • Moshi — libreria JSON di Square per Kotlin e Android senza riflessione
  • Adattatore Kotlin — supporto integrato per data class, valori predefiniti e sicurezza nulla
  • @Json — annotazione per configurare il nome del campo e ignorare proprietà
  • Adattatori — logica di serializzazione personalizzata tramite @ToJson e @FromJson
  • Generazione codice — Moshi genera adattatori in fase di compilazione tramite kapt o KSP

Cos'è Moshi

Moshi è una libreria JSON per JVM, Android e Kotlin Multiplatform, creata da Square (gli autori di OkHttp e Retrofit). A differenza di Gson, Moshi non si basa sulla riflessione — gli adattatori vengono generati in fase di compilazione tramite l'annotazione @JsonClass(generateAdapter = true). Ciò rende Moshi più veloce, sicura e prevedibile quando si lavora con costrutti specifici di Kotlin.

Filosofia e vantaggi

La differenza principale tra Moshi e i suoi predecessori è il rifiuto della riflessione. La riflessione consente a Gson di funzionare con qualsiasi classe senza preparazione, ma il costo è un'inizializzazione lenta, l'impossibilità di ottimizzazione da parte del compilatore e il rischio di errori in fase di esecuzione. Moshi richiede una dichiarazione esplicita delle classi per la generazione del codice, ma in cambio offre la velocità del codice scritto a mano e la piena sicurezza dei tipi in fase di compilazione.

kotlin
// Aggiungere Moshi a 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"
}

// Modello semplice con generazione di codice
@JsonClass(generateAdapter = true)
data class User(
    @Json(name = "user_id")
    val id: Int,
    val name: String,
    val email: String,
    val avatar: String? = null
)

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

Installazione e configurazione

Per iniziare a lavorare con Moshi, è necessario aggiungere dipendenze al build.gradle e annotare i modelli. Moshi.Builder funge da punto di ingresso: attraverso di esso vengono aggiunti adattatori integrati per i tipi standard, adattatori personalizzati e configurato il comportamento della libreria. Moshi supporta adattatori per Date, Enum, Collection e Map nativamente, ma le classi Kotlin richiedono il modulo moshi-kotlin. A differenza di Gson, Moshi non utilizza la riflessione per le classi Kotlin per impostazione predefinita — per questo viene collegato KotlinJsonAdapterFactory, che funge da fallback quando la generazione del codice non viene utilizzata o la classe non è annotata con @JsonClass. Questo approccio garantisce che lo sviluppatore scelga esplicitamente tra le prestazioni della generazione del codice e la flessibilità della riflessione per ogni classe specifica.

Creazione di Moshi e aggiunta di adattatori

Dopo aver costruito Moshi tramite Builder, lo sviluppatore ottiene un'istanza di Moshi e richiede un adattatore per la classe desiderata. JsonAdapter è l'oggetto centrale che esegue la serializzazione tramite toJson() e la deserializzazione tramite fromJson(). Moshi utilizza automaticamente l'adattatore generato se la classe è annotata con @JsonClass(generateAdapter = true), altrimenti applica il KotlinJsonAdapterFactory riflessivo come fallback. Questo approccio combina la velocità della generazione del codice con la flessibilità di un meccanismo riflessivo per progetti di qualsiasi scala e complessità. Moshi è adatto sia per piccole applicazioni che per grandi progetti aziendali con centinaia di modelli di dati.

kotlin
// Configurare Moshi con KotlinJsonAdapterFactory
val moshi = Moshi.Builder()
    .add(KotlinJsonAdapterFactory())
    .add(LocalDateAdapter())
    .build()

// Usare l'adattatore
val adapter = moshi.adapter(User::class.java)

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

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

// Lavorare con le liste
val listAdapter = moshi.adapter(
    Types.newParameterizedType(
        List::class.java,
        User::class.java
    )
)

Annotazioni e adattatori

Moshi utilizza annotazioni per configurare la serializzazione e supportare tipi personalizzati. @Json(name = "...") imposta la chiave JSON per un campo. @Transient esclude un campo dalla serializzazione. @JsonClass(generateAdapter = true) abilita la generazione del codice. Per la logica personalizzata, Moshi fornisce le annotazioni @ToJson e @FromJson, che possono essere posizionate in una classe adattatrice separata.

@Json e adattatori personalizzati

L'annotazione @Json sostituisce @SerializedName di Gson e funziona in modo simile: il campo kotlinName viene associato alla chiave JSON "kotlin_name". Per i tipi che Moshi non può serializzare per impostazione predefinita (ad esempio LocalDate), lo sviluppatore crea una classe con metodi @ToJson e @FromJson. Gli adattatori vengono registrati tramite Moshi.Builder.add() e si applicano globalmente o a un tipo specifico. Moshi supporta classi sealed e serializzazione polimorfica tramite @JsonClass con un discriminatore esplicito, consentendo di lavorare con gerarchie di tipi in JSON senza controllo manuale dei campi. Durante la deserializzazione, Moshi ignora per impostazione predefinita le chiavi JSON sconosciute, garantendo la compatibilità all'indietro quando si aggiungono nuovi campi lato server senza modificare il codice client. Per il debug, è possibile attivare la modalità rigorosa tramite failOnUnknown, che genera un'eccezione quando vengono trovate chiavi sconosciute.

kotlin
// Adattatore personalizzato per 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)
    }
}

// Modello con annotazioni 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
)

// Registrare l'adattatore
val moshi = Moshi.Builder()
    .add(LocalDateAdapter())
    .add(KotlinJsonAdapterFactory())
    .build()

Moshi vs Gson

Confrontare Moshi e Gson è una domanda comune quando si sceglie una libreria JSON per un progetto Android. Moshi vince nello sviluppo moderno con Kotlin grazie alla generazione del codice, alla sicurezza nulla e alla velocità. Gson rimane rilevante per progetti Java, codice legacy e scenari in cui la configurazione minima è importante. La differenza diventa evidente con grandi volumi di dati e modelli complessi.

Prestazioni e sicurezza

I test delle prestazioni mostrano che Moshi con generazione di codice è 2–5 volte più veloce di Gson nelle operazioni di serializzazione e deserializzazione. Il vantaggio principale di Moshi è la corretta gestione della sicurezza nulla di Kotlin: se un campo è assente in JSON e il modello lo dichiara come non nullo senza valore predefinito, Moshi genera un'eccezione al momento della deserializzazione, prevenendo errori nascosti.

CaratteristicaGsonMoshi
Meccanismoriflessionegenerazione codice / riflessione
sicurezza nullanon considerapieno supporto Kotlin
Velocitàmediaalta
Valori predefinitinon supportasupporta
Kotlin Multiplatformno
Dimensione libreria~240 Kb~150 Kb

La scelta tra Moshi e Gson dipende dal contesto del progetto. I nuovi progetti in Kotlin traggono vantaggio da Moshi grazie alla sicurezza dei tipi e alle prestazioni. Gson rimane una scelta ragionevole per supportare codice Java, strutture JSON dinamiche o quando la semplicità di configurazione è più importante della velocità. Per Kotlin Multiplatform, Moshi è l'unica delle due opzioni che supporta questa piattaforma.

Durante la migrazione da Gson a Moshi, le modifiche principali riguardano annotazioni e adattatori. @SerializedName di Gson viene sostituito con @Json(name = "..."), e JsonSerializer/JsonDeserializer personalizzati con la coppia @ToJson/@FromJson. Per i modelli con valori predefiniti e campi nullable, Moshi si comporta in modo più prevedibile: se un campo non nullo senza valore predefinito è assente in JSON, Moshi genera JsonDataException, prevenendo NPE nascosti. L'integrazione con Retrofit tramite MoshiConverterFactory viene aggiunta con una singola dipendenza e non richiede la modifica dell'architettura del livello di rete. Per l'offuscamento tramite ProGuard o R8, è necessario aggiungere regole per preservare le classi annotate con @JsonClass e gli adattatori generati, altrimenti la serializzazione si romperà nella build di rilascio. Nel complesso, la migrazione da Gson a Moshi è giustificata nei nuovi progetti Kotlin dove prestazioni e sicurezza dei tipi sono importanti.

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

// Gson: funziona tramite riflessione
val gson = Gson()
val fromGson = gson.fromJson("""{"name":"test"}""",
    Sample::class.java)
// count = 0 (predefinito), ma la sicurezza nulla non viene verificata

// Moshi: richiede un adattatore, la sicurezza nulla è esplicita
@JsonClass(generateAdapter = true)
data class SampleMoshi(
    val name: String,
    val count: Int,
    val tags: List<String> = listOf()
)

Domande frequenti

Cos'è Moshi in Android?

Moshi è una libreria JSON di Square per Kotlin e Android che utilizza la generazione di codice invece della riflessione. Fornisce prestazioni elevate, corretta gestione della sicurezza nulla di Kotlin e compatibilità con Kotlin Multiplatform.

In cosa Moshi è migliore di Gson?

Moshi supera Gson in velocità (2–5 volte più veloce grazie alla generazione di codice), sicurezza (rispetta le annotazioni nulle di Kotlin) e dimensione (~90 Kb più piccolo). Moshi supporta anche Kotlin Multiplatform e i valori predefiniti in data class.

Come funziona l'annotazione @JsonClass in Moshi?

@JsonClass(generateAdapter = true) indica a Moshi di generare un adattatore per la classe specificata in fase di compilazione. L'adattatore generato esegue la serializzazione direttamente, senza riflessione, offrendo le massime prestazioni.

Come creare un adattatore Moshi personalizzato?

Crea una classe con metodi annotati con @ToJson (serializzazione) e @FromJson (deserializzazione). Registra l'istanza tramite Moshi.Builder.add(). Moshi troverà e applicherà automaticamente l'adattatore quando lavora con il tipo corrispondente.

Moshi supporta Kotlin Multiplatform?

Sì, Moshi supporta Kotlin Multiplatform a partire dalla versione 1.13.0. Ciò lo rende l'unica soluzione JSON popolare per progetti KMP, consentendo di utilizzare codice di serializzazione comune su tutte le piattaforme target.

Riepilogo

  • Moshi — libreria JSON moderna di Square con generazione di codice invece di riflessione
  • @JsonClass — annotazione per la generazione di adattatori, che offre velocità del codice scritto a mano
  • @Json — configurazione delle chiavi JSON, @Transient — esclusione dei campi dalla serializzazione
  • @ToJson e @FromJson — API semplice per adattatori personalizzati di qualsiasi tipo
  • Sicurezza nulla — Moshi rispetta le annotazioni Kotlin e genera un'eccezione in caso di mancata corrispondenza
  • Prestazioni — da 2 a 5 volte più veloce di Gson nelle operazioni di serializzazione e deserializzazione
  • Kotlin Multiplatform — supporto KMP per codice di serializzazione universale

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche