【Kotlin/Android Studio】Moshiの使い方!JSONをパースする方法
この記事からわかること
- Android Studio/KotlinでRetrofit × Moshiの使い方
- QiitaAPIを使用した記事取得アプリの実装方法
- JSONデータをパースする
- アノテーションの使い方
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
参考文献:公式リファレンス:moshi
環境
- Android Studio:Flamingo
- Kotlin:1.8.20
Moshiとは?
MoshiはAndroidアプリ開発で簡単にJSONデータをパース(変換)できるコンバーターライブラリです。開発したのはSquare社という会社でオープンソースのライブラリになっています。同じ会社が開発した簡単にHTTP通信を実装できるライブラリRetrofitと使い合わせて使用されることが多く、アプリ開発ではよく登場するAPI(RESTful API)を利用するためにはRetrofit × Moshiは欠かせない存在です。
JSONデータはネストすればするほど複雑になりそれをKotlin内で扱うためのクラスと紐付ける作業は規模によりとんでもない作業量と複雑性が生まれます。Moshiを利用することで受け取ったJSONに当てはめたいデータクラスを定義するだけで簡単にマッピングしてくれます。
Moshiの使い方
実際に実装するために今回はQiitaの記事情報を取得できるAPIを使用していきます。APIのエンドポイントは以下のURLでここから記事情報が以下のJSON形式で返ってきます。
レスポンスで受け取るJSON
[{
"id": "記事の一意のID",
"title": "記事のタイトル",
"body": "記事の本文",
"created_at": "記事の作成日時",
"updated_at": "記事の更新日時",
"user": {
"id": "ユーザーの一意のID",
"name": "ユーザー名",
"profile_image_url": "ユーザーのプロフィール画像のURL"
},
// .....他にもさまざまな情報
}]
またMoshiのみの使い方というよりRetrofit × Moshiの使い方になるのでご理解ください。
実装の流れ
Retrofitを使用したHTTP通信の実装方法は以下の記事を参考にしてください。今回はこの記事の続きとしてコンバーターをGSONを使っていた箇所をmoshiに切り替えていきたいと思います。また前回の記事については全体のコードをGitHubに上げているので今回の記事に流用してください。
- 依存関係の追加
- JSONにマッピングするデータクラスの作成
- コンバーターとして渡す
依存関係の追加
MoshiをAndroid Studio内で使用できるようにするには依存関係を追加する必要があります。追加する箇所が多いので間違えないように注意してください。またksp
はアノテーションをKotlinで使用できるようにするためのものです。同じようなライブラリにkaptがありますがKSPへの置き換えが推奨されているようです。
plugins {
// 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
id 'com.google.devtools.ksp' version '1.6.20-1.0.4' apply false
}
plugins {
// 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
id "com.google.devtools.ksp"
}
dependencies {
// 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
implementation "com.squareup.retrofit2:converter-moshi:2.9.0"
implementation "com.squareup.moshi:moshi:1.12.0"
implementation "com.squareup.moshi:moshi-kotlin:1.12.0"
}
JSONにマッピングするデータクラスの作成
Moshiの特徴はJSONにマッピングするデータクラスの作成をする際に@JsonClass
などのアノテーションを使用することです。@JsonClass(generateAdapter = true)
を付与することでmoshiがこのデータクラスを認識してくれます。
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class Article(
val id: String,
val title: String,
val body: String,
val created_at: String,
val updated_at: String,
val user: User
)
@JsonClass(generateAdapter = true)
data class User(
val id: String,
val name: String,
val profile_image_url: String
)
コンバーターとして渡す
あとはコンバーターとしてRetrofitインスタンスに渡すだけです。
private val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
private val retrofit = Retrofit.Builder()
.addConverterFactory(MoshiConverterFactory.create(moshi))
.baseUrl(BASE_URL)
.build()
Moshiで使用できるアノテーションの種類と役割
これだけではあまりMoshiを使うメリットが感じられないかもしれませんが、Moshiにはさまざまなアノテーションが定義されており、特定のカラムに対して独自の変換ルールを適用することができるため、柔軟な処理が可能になっています。
@Json
@Json
アノテーションを付与することでプロパティ名をJSONのキー値と一致していなくても正常に変換させることが可能になります。
@JsonClass(generateAdapter = true)
data class User(
@Json(name = "user_id") val userId: String,
@Json(name = "display_name") val displayName: String
)
他にも使用できるコンバーターの種類
- GSON:
com.squareup.retrofit2:converter-gson:$version_retrofit
- Jackson:
com.squareup.retrofit2:converter-jackson:$version_retrofit
- moshi:
com.squareup.retrofit2:converter-moshi:$version_retrofit
- protocol-buffers:
com.squareup.retrofit2:converter-protobuf:$version_retrofit
- ワイヤー:
com.squareup.retrofit2:converter-wire:$version_retrofit
- 単純な XML:
com.squareup.retrofit2:converter-simplexml:$version_retrofit
- JAXB:
com.squareup.retrofit2:converter-jaxb:$version_retrofit
- Scalars:
com.squareup.retrofit2:converter-scalars:$version_retrofit
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。