Moshi's Custom Adapter with RxAndroid & Retrofit & Kotlin

If you just need the User object. There is a library called Moshi-Lazy-Adapters that provides a @Wrapped annotation, that allows specifying the path to the desired object. All you have to do is add the respective adapter to your Moshi instance and change the service code to:

interface AccountService {

  @GET("u/17350105/test.json")
  @Wrapped("user")
  fun signUpAnonymously() : Observable<User>
}

No need for any other custom adapter.


You can solve the problem by changing your code to do something like below.

Basically in your case when the UserAdapter is registered, it tells moshi that it can create a User only from UserJson object. Hence Moshi does not recognize the JSON object with keyword user.

By adding an indirection in form of User1 (please pardon the naming convention), the UserJson is created properly with User1 from JSON.

class User(var username: String)

class User1(var username: String) // I introduced this class
class UserJson(var message: String, var user: User1) // changed User to User1

class UserAdapter {
    @FromJson fun fromJson(userJson: UserJson): User {
        println("message = ${userJson.message}")        
        println("user = ${userJson.user}")              
        return User(userJson.user.username)
    }
}