Instruction 2
Connecting Moshi with Retrofit
Using Moshi adapters to parse JSON manually can be useful when you need to write something into a file or shared preferences, or do some other operation with the data. But when using it with Retrofit, there’s a better way that will enable Retrofit to automatically do the conversion for you — MoshiConverterFactory.
Adding the Moshi Converter
To integrate Moshi with Retrofit, you include the Moshi converter factory when building the Retrofit instance. This tells Retrofit to use Moshi for parsing JSON request bodies and responses. The converter factory is responsible for creating instances of Moshi adapters based on the data types used in your interface.
With the converter in place, Retrofit automatically serializes request bodies to JSON and deserializes API responses to Kotlin objects. When you define a method in your Retrofit interface to return a custom model, Retrofit — with the help of Moshi — parses the JSON response into that model. This seamless integration reduces the boilerplate code for parsing and increases the reliability of data handling in your app.
Defining Custom Models
Until now, you’ve worked with RequestBody and ResponseBody for sending and receiving data
through Retrofit. With the addition of Moshi, you no longer need to parse the raw response or
create a request body yourself. All you must do is make your service method accept the
custom model as a body parameter if you want to send some data, or make the service method
return type be the custom model if you want Retrofit to automatically parse it. Here’s an example:
@GET("user")
fun getUser(): Call<UserResponse>
When you make the API call to get user data, Retrofit automatically parses the response into
an instance of UserResponse — if the JSON schema matches the custom model, of course. Otherwise,
it throws an error.
Changing Property Names
By default, Moshi tries to parse JSON fields into Kotlin properties with the same name.
Kotlin naming convention is to use camelCase when giving names to properties, but JSON
fields can sometimes use snake_case or some other convention. You can use @Json to specify how
Kotlin properties map to JSON names. Here’s an example:
"last_name": "Kordic",
data class User(
@Json(name = "last_name") val lastName: String,
)
The JSON sample has a field called last_name. This doesn’t fit the naming convention
used in Kotlin, so you tell Moshi that you want it to bind last_name from JSON to a Kotlin
property named lastName.
Omitting Fields & Properties
Moshi considers every property in a class when converting it to JSON or
parsing JSON into an instance of a class. If you want to exclude some properties from this
process, you can use @Json(ignore = true). The following code is an example of this:
data class User(
val lastName: String,
@Json(ignore = true)
val address: String = "placeholder address"
)
Run the app, register an account and check the logcat:
{
"lastName": "Kordic"
}
You can see that Moshi ignored the address property and it’s missing from the JSON output.
Similarly, if a field in the JSON matches the ignored property in the class, Moshi
ignores it when parsing. Here’s an example:
{
"lastName": "Kordic",
"address": "Osijek"
}
Run the app, register an account and check the logcat:
User(lastName=Kordic, address=placeholder address)
You can see that even though the address field exists in JSON, Moshi completely ignored it
during parsing.
Note: It’s important to remember that if you use
@Json(ignore = true)on a property, the property must have a default value.
Moshi offers more features that are out of this module’s scope. If you want to learn more, check out the official docs.
In the upcoming demo section, you’ll connect Moshi with Retrofit and use it to auto-parse your requests and responses.