Moshi: conceitos-chave, biblioteca JSON para Kotlin e como funciona

Autor: IT Sectr Publicado: 2026-03-15 Tempo de leitura: 8 min

Moshi é uma biblioteca JSON moderna da Square, criada especificamente para Kotlin e Android levando em conta as limitações do Gson. Ela é totalmente compatível com a segurança nula do Kotlin, gera código em tempo de compilação e não usa reflexão, o que melhora o desempenho e a confiabilidade. De acordo com Square Moshi, 2024, Moshi fornece serialização previsível e suporta adaptadores personalizados para qualquer tipo de dados.

Pontos principais

  • Moshi — biblioteca JSON da Square para Kotlin e Android sem reflexão
  • Adaptador Kotlin — suporte integrado para data class, valores padrão e segurança nula
  • @Json — anotação para configurar nome do campo e ignorar propriedades
  • Adaptadores — lógica de serialização personalizada via @ToJson e @FromJson
  • Geração de código — Moshi gera adaptadores em tempo de compilação via kapt ou KSP

O que é Moshi

Moshi é uma biblioteca JSON para JVM, Android e Kotlin Multiplatform, criada pela Square (os autores do OkHttp e Retrofit). Ao contrário do Gson, Moshi não depende de reflexão — os adaptadores são gerados em tempo de compilação através da anotação @JsonClass(generateAdapter = true). Isso torna Moshi mais rápida, segura e previsível ao trabalhar com construções específicas do Kotlin.

Filosofia e vantagens

A principal diferença do Moshi em relação aos seus antecessores é a rejeição da reflexão. A reflexão permite que o Gson trabalhe com qualquer classe sem preparação, mas o custo é uma inicialização lenta, a impossibilidade de otimização pelo compilador e o risco de erros em tempo de execução. Moshi exige declaração explícita de classes para geração de código, mas em troca oferece a velocidade do código escrito à mão e segurança total de tipos em tempo de compilação.

kotlin
// Adicionar Moshi ao 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"
}

// Modelo simples com geração de código
@JsonClass(generateAdapter = true)
data class User(
    @Json(name = "user_id")
    val id: Int,
    val name: String,
    val email: String,
    val avatar: String? = null
)

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

Instalação e configuração

Para começar a trabalhar com Moshi, é necessário adicionar dependências ao build.gradle e anotar os modelos. Moshi.Builder serve como ponto de entrada: através dele são adicionados adaptadores integrados para tipos padrão, adaptadores personalizados e configurado o comportamento da biblioteca. Moshi suporta adaptadores para Date, Enum, Collection e Map nativamente, mas as classes Kotlin exigem o módulo moshi-kotlin. Ao contrário do Gson, Moshi não usa reflexão para classes Kotlin por padrão — para isso, o KotlinJsonAdapterFactory é conectado, servindo como alternativa quando a geração de código não é usada ou a classe não está anotada com @JsonClass. Essa abordagem garante que o desenvolvedor escolha explicitamente entre o desempenho da geração de código e a flexibilidade da reflexão para cada classe específica.

Criando Moshi e adicionando adaptadores

Após construir Moshi através do Builder, o desenvolvedor obtém uma instância de Moshi e solicita um adaptador para a classe desejada. JsonAdapter é o objeto central que realiza a serialização via toJson() e a desserialização via fromJson(). Moshi usa automaticamente o adaptador gerado se a classe estiver anotada com @JsonClass(generateAdapter = true), caso contrário aplica o KotlinJsonAdapterFactory reflexivo como alternativa. Essa abordagem combina a velocidade da geração de código com a flexibilidade de um mecanismo reflexivo para projetos de qualquer escala e complexidade. Moshi é adequada tanto para aplicações pequenas quanto para grandes projetos empresariais com centenas de modelos de dados.

kotlin
// Configurar Moshi com KotlinJsonAdapterFactory
val moshi = Moshi.Builder()
    .add(KotlinJsonAdapterFactory())
    .add(LocalDateAdapter())
    .build()

// Usar o adaptador
val adapter = moshi.adapter(User::class.java)

// Serialização
val user = User(1, "Alice", "alice@test.com")
val json = adapter.toJson(user)

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

// Trabalhar com listas
val listAdapter = moshi.adapter(
    Types.newParameterizedType(
        List::class.java,
        User::class.java
    )
)

Anotações e adaptadores

Moshi usa anotações para configurar a serialização e suportar tipos personalizados. @Json(name = "...") define a chave JSON para um campo. @Transient exclui um campo da serialização. @JsonClass(generateAdapter = true) ativa a geração de código. Para lógica personalizada, Moshi fornece as anotações @ToJson e @FromJson, que podem ser colocadas em uma classe adaptadora separada.

@Json e adaptadores personalizados

A anotação @Json substitui o @SerializedName do Gson e funciona de forma semelhante: o campo kotlinName é associado à chave JSON "kotlin_name". Para tipos que Moshi não consegue serializar por padrão (por exemplo, LocalDate), o desenvolvedor cria uma classe com métodos @ToJson e @FromJson. Os adaptadores são registrados via Moshi.Builder.add() e aplicados globalmente ou a um tipo específico. Moshi suporta classes seladas e serialização polimórfica via @JsonClass com um discriminador explícito, permitindo trabalhar com hierarquias de tipos em JSON sem verificação manual de campos. Durante a desserialização, Moshi ignora chaves JSON desconhecidas por padrão, garantindo compatibilidade reversa ao adicionar novos campos no servidor sem alterar o código do cliente. Para depuração, o modo estrito pode ser ativado via failOnUnknown, que lança uma exceção quando chaves desconhecidas são encontradas.

kotlin
// Adaptador personalizado para 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)
    }
}

// Modelo com anotações 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
)

// Registrar o adaptador
val moshi = Moshi.Builder()
    .add(LocalDateAdapter())
    .add(KotlinJsonAdapterFactory())
    .build()

Moshi vs Gson

Comparar Moshi e Gson é uma pergunta comum ao escolher uma biblioteca JSON para um projeto Android. Moshi vence no desenvolvimento moderno com Kotlin graças à geração de código, segurança nula e velocidade. Gson continua relevante para projetos Java, código legado e cenários onde a configuração mínima é importante. A diferença torna-se perceptível com grandes volumes de dados e modelos complexos.

Desempenho e segurança

Testes de desempenho mostram que Moshi com geração de código é 2–5 vezes mais rápido que Gson em operações de serialização e desserialização. A principal vantagem do Moshi é o tratamento correto da segurança nula do Kotlin: se um campo estiver ausente no JSON e o modelo o declarar como non-null sem valor padrão, Moshi lança uma exceção no momento da desserialização, prevenindo erros ocultos.

CaracterísticaGsonMoshi
Mecanismoreflexãogeração de código / reflexão
Segurança nulanão considerasuporte completo ao Kotlin
Velocidademédiaalta
Valores padrãonão suportasuporta
Kotlin Multiplatformnãosim
Tamanho da biblioteca~240 Kb~150 Kb

A escolha entre Moshi e Gson depende do contexto do projeto. Novos projetos em Kotlin se beneficiam do Moshi graças à segurança de tipos e desempenho. Gson continua sendo uma escolha razoável para suportar código Java, estruturas JSON dinâmicas ou quando a simplicidade de configuração é mais importante que a velocidade. Para Kotlin Multiplatform, Moshi é a única das duas opções que suporta esta plataforma.

Ao migrar de Gson para Moshi, as principais mudanças dizem respeito a anotações e adaptadores. O @SerializedName do Gson é substituído por @Json(name = "..."), e os JsonSerializer/JsonDeserializer personalizados pelo par @ToJson/@FromJson. Para modelos com valores padrão e campos anuláveis, Moshi se comporta de forma mais previsível: se um campo non-null sem padrão estiver ausente no JSON, Moshi lança JsonDataException, prevenindo NPEs ocultos. A integração com Retrofit via MoshiConverterFactory é adicionada com uma única dependência e não requer alteração na arquitetura da camada de rede. Para ofuscação via ProGuard ou R8, é necessário adicionar regras para preservar classes anotadas com @JsonClass e adaptadores gerados, caso contrário a serialização quebrará na compilação de release. No geral, a migração de Gson para Moshi é justificada em novos projetos Kotlin onde desempenho e segurança de tipos são importantes.

kotlin
// Comparação de serialização: Gson vs Moshi
data class Sample(
    val name: String,
    val count: Int,
    val tags: List<String> = listOf()
)

// Gson: funciona através de reflexão
val gson = Gson()
val fromGson = gson.fromJson("""{"name":"test"}""",
    Sample::class.java)
// count = 0 (padrão), mas segurança nula não é verificada

// Moshi: requer um adaptador, segurança nula é explícita
@JsonClass(generateAdapter = true)
data class SampleMoshi(
    val name: String,
    val count: Int,
    val tags: List<String> = listOf()
)

Perguntas frequentes

O que é Moshi no Android?

Moshi é uma biblioteca JSON da Square para Kotlin e Android que usa geração de código em vez de reflexão. Ela fornece alto desempenho, tratamento correto da segurança nula do Kotlin e compatibilidade com Kotlin Multiplatform.

Como Moshi é melhor que Gson?

Moshi supera Gson em velocidade (2–5 vezes mais rápido graças à geração de código), segurança (respeita anotações nulas do Kotlin) e tamanho (~90 Kb menor). Moshi também suporta Kotlin Multiplatform e valores padrão em data class.

Como funciona a anotação @JsonClass no Moshi?

@JsonClass(generateAdapter = true) instrui Moshi a gerar um adaptador para a classe dada em tempo de compilação. O adaptador gerado realiza a serialização diretamente, sem reflexão, proporcionando máximo desempenho.

Como criar um adaptador personalizado Moshi?

Crie uma classe com métodos anotados com @ToJson (serialização) e @FromJson (desserialização). Registre a instância via Moshi.Builder.add(). Moshi encontrará e aplicará automaticamente o adaptador ao trabalhar com o tipo correspondente.

Moshi suporta Kotlin Multiplatform?

Sim, Moshi suporta Kotlin Multiplatform a partir da versão 1.13.0. Isso faz dele a única solução JSON popular para projetos KMP, permitindo usar código de serialização comum em todas as plataformas alvo.

Resumo

  • Moshi — biblioteca JSON moderna da Square com geração de código em vez de reflexão
  • @JsonClass — anotação para geração de adaptador, oferecendo velocidade de código escrito à mão
  • @Json — configuração de chaves JSON, @Transient — exclusão de campos da serialização
  • @ToJson e @FromJson — API simples para adaptadores personalizados de qualquer tipo
  • Segurança nula — Moshi respeita anotações Kotlin e lança exceção em caso de incompatibilidade
  • Desempenho — 2–5 vezes mais rápido que Gson em operações de serialização e desserialização
  • Kotlin Multiplatform — suporte KMP para código de serialização universal

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também