Adapters for Common Types

The moshi-adapters artifact provides useful, pre-built adapters for common types that are not included in the core moshi library.

To use these adapters, first add the dependency to your project:

Gradle (Kotlin DSL)

implementation("com.squareup.moshi:moshi-adapters:1.15.2")

Rfc3339DateJsonAdapter

This adapter serializes and deserializes java.util.Date objects using the RFC 3339 format, which is a common standard for timestamps in APIs (e.g., 2023-10-27T10:00:00Z).

Usage

Register the adapter for the Date class when building your Moshi instance.

import com.squareup.moshi.Moshi
import com.squareup.moshi.adapters.Rfc3339DateJsonAdapter
import java.util.Date

val moshi = Moshi.Builder()
    .add(Date::class.java, Rfc3339DateJsonAdapter())
    .build()

Now, any Date property in your models will be handled automatically.

@JsonClass(generateAdapter = true)
data class Event(val name: String, val start: Date)

val adapter = moshi.adapter(Event::class.java)

// Serialization
val event = Event("Moshi Meetup", Date())
val json = adapter.toJson(event) // Output: {"name":"Moshi Meetup","start":"...Z"}

// Deserialization
val eventFromJson = adapter.fromJson(json)

This adapter is null-safe, meaning it will correctly handle null Date properties.

EnumJsonAdapter

While Moshi's default enum adapter is sufficient for most cases, it throws a JsonDataException if it encounters a JSON string that doesn't match any of the enum's constants. EnumJsonAdapter provides a way to gracefully handle unknown values by providing a fallback.

Usage

Create an instance of EnumJsonAdapter for your enum class and configure it with withUnknownFallback().

enum class Status { ACTIVE, INACTIVE, DELETED, UNKNOWN }

val moshi = Moshi.Builder()
    .add(
        Status::class.java,
        EnumJsonAdapter.create(Status::class.java)
            .withUnknownFallback(Status.UNKNOWN)
    )
    .build()

Now, if the JSON contains a status value that is not "ACTIVE", "INACTIVE", or "DELETED", it will deserialize to Status.UNKNOWN instead of crashing.

val adapter = moshi.adapter(Status::class.java)

// "PENDING" is not a known constant
val status = adapter.fromJson("\"PENDING\"") // Returns Status.UNKNOWN

// Known constants work as expected
val activeStatus = adapter.fromJson("\"ACTIVE\"") // Returns Status.ACTIVE

This is particularly useful for maintaining forward compatibility with APIs that might add new enum values over time.