1

Kotlin’s a great language for JSON

 2 years ago
source link: https://developer.squareup.com/blog/kotlins-a-great-language-for-json/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
May 15th, 2017 | 2 minute read

Kotlin’s a great language for JSON

Why you should model your JSON documents with Kotlin

Twitter
Facebook
Reddit
LinkedIn

Though it has its wrinkles, I really like JSON. It’s easy to read, pretty fast to parse, and refreshingly simple. Here’s a sample message from GitHub’s exemplar API:

{
  "url": "https://api.github.com/repos/square/okio/issues/156",
  "id": 91393390,
  "number": 156,
  "title": "ByteString CharSequence idea",
  "state": "open",
  "created_at": "2015-06-27T00:49:40.000Z",
  "body": "Let's make CharSequence that's backed by bytes.\n"
}

Kotlin’s concise immutable data classes make it easy to build a basic model for this JSON.

data class Issue(
    val url: String,
    val id: Long,
    val number: Long,
    val title: String,
    val state: String,
    val created_at: String,
    val body: String)

That’s it. No equals(), hashCode(), or toString() boilerplate. We don’t even need a builder! Let’s extend the model to take advantage of Kotlin’s default values and explicit nulls:

data class Issue(
    val url: String,
    val id: Long,
    val number: Long,
    val title: String,
    **val comments: Long = 0L**,
    val created_at: String,
    **val closed_at: String?,**
    **val body: String = ""**)

Default values fill in the gaps when decoding JSON from the network. I like that I can leave them out when creating sample data in my test cases. Explicit nullable types prevent data problems.

Today we’re releasing Moshi 1.5 with powerful Kotlin support via the moshi-kotlin module. Moshi’s type adapters and annotations bind JSON to an idiomatic data model.

data class Issue(
    val url: String,
    val id: Long,
    val number: Long,
    val title: String,
    **val state: IssueState**,
    val comments: Long = 0L,
    **@Json(name = "created_at") val createdAt: Date**,
    **@Json(name = "closed_at") val closedAt: Date?**,
    val body: String = "")

This class uses proper types instead of strings for the issue’s state and timestamps. The @Json annotation maps snake_case names in JSON to camelCase property names in Kotlin.

To set this up I need a Moshi.Builder and a JsonAdapter. I can use Kotlin’s raw strings to embed a sample message right in the code.

val issueJson = """
{
  "url": "[https://api.github.com/repos/square/okio/issues/156](https://api.github.com/repos/square/okio/issues/156)",
  "id": 91393390,
  "number": 156,
  "title": "ByteString CharSequence idea",
  "state": "open",
  "created_at": "2015-06-27T00:49:40.000Z"
}
"""

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

val issueAdapter = moshi.adapter(Issue::class.java)
val issue = issueAdapter.fromJson(issueJson)

If you’re using JSON, Moshi and Kotlin help you to build better models with less code. Note that moshi-kotlin uses kotlin-reflect for property binding. That dependency is large by Android standards (1.7 MiB / 11,500 methods). We’re thinking of creative ways to address that!

This post is part of Square’s “Square Open Source ♥s Kotlin” series.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK