Basic Usage

Moshi's core functionality revolves around the Moshi class and JsonAdapters. This guide covers the fundamental concepts for serializing and deserializing common types.

The Moshi Class

The Moshi class is the main entry point for the library. You create an instance using Moshi.Builder:

import com.squareup.moshi.Moshi

val moshi = Moshi.Builder().build()

This basic instance can handle standard Java and Kotlin types:

  • Primitives (Int, Double, Boolean, etc.) and their boxed counterparts.
  • Strings
  • Enums
  • Arrays, Collections (Lists, Sets), and Maps

JsonAdapters

A JsonAdapter is responsible for converting a specific type to and from JSON. You get an adapter from a Moshi instance:

val stringAdapter: JsonAdapter<String> = moshi.adapter(String::class.java)
val listOfIntsAdapter: JsonAdapter<List<Int>> = moshi.adapter(
    Types.newParameterizedType(List::class.java, Integer::class.java)
)

Once you have an adapter, you can use toJson() and fromJson():

val names = listOf("Alice", "Bob")
val listAdapter: JsonAdapter<List<String>> = moshi.adapter(
    Types.newParameterizedType(List::class.java, String::class.java)
)

// Serialization
val json: String = listAdapter.toJson(names) // Output: ["Alice","Bob"]

// Deserialization
val parsedNames: List<String>? = listAdapter.fromJson(json)

Moshi automatically caches adapters, so it's efficient to call moshi.adapter() whenever you need one.

Working with Your Own Classes

Moshi can serialize your custom classes without any configuration if they are written in Java and follow standard conventions. For Kotlin classes, you need to enable Kotlin support. (See Kotlin Support).

Let's consider a simple Player class:

// Assumes Kotlin support is enabled
data class Player(val username: String, val score: Int)

Moshi will map the properties of the class to the keys in the JSON object. The field names are used as the JSON keys by default.

val moshi: Moshi = Moshi.Builder()
    .addLast(KotlinJsonAdapterFactory()) // For Kotlin reflection
    .build()

val playerAdapter: JsonAdapter<Player> = moshi.adapter(Player::class.java)

// Serialize an instance
val player = Player("jesse", 100)
val playerJson = playerAdapter.toJson(player)
// Output: {"score":100,"username":"jesse"}

// Deserialize a JSON string
val newPlayer = playerAdapter.fromJson("{"username":"jake","score":99}")
// newPlayer is Player(username="jake", score=99)

Note that the order of keys in the output JSON is not guaranteed unless you are using a class with a stable property order, like a Kotlin data class.