LoginSignup
9
5

More than 5 years have passed since last update.

ケースクラスをJSON化するときにフィールド名を自動的にスネークケースにする方法(circe-generic-extras)

Last updated at Posted at 2018-06-22

目的

できるだけEncoder/Decoderを書かずに、ケースクラスをJSON化したいときは、import io.circe.generic.auto._, io.circe.syntax._をインポートして hoge.asJsonとすればよいが、キャメルケースのフィールド名がそのままJSONに出力されてしまう。これを簡単にスネークケースにできないか? という感じでツイートしてたら教えてもらいました。それを共有します。

import io.circe._
import io.circe.syntax._
import io.circe.genric.auto._

case class UserName(firstName: String, lastName: String)

val userName = UserName(firstName = "Junichi", lastName = "Kato")
val json = userName.asJson

/*
{
  "firstName": "Junichi",
  "lastName": "Kato"
}
*/

今までのやり方

最初にやってたのはこれ。タイピング数が多くなる(笑)

import io.circe._

case class UserName(firstName: String, lastName: String)

object UserName {

  implicit val userNameDecoder: Decoder[UserName] = Decoder.instance{ v =>
    Json.obj(
      "first_name" -> v.firstName.asJson,
      "last_name" -> v.lastName.asJson
    )
  }

}

次はforProduct??メソッド。こっちはかなり楽になった。

import io.circe._

case class UserName(firstName: String, lastName: String)

object UserName {

  implicit val userNameDecoder: Decoder[UserName] = 
    Decoder.forProduct2("first_name", "last_name")(UserName.apply)

}

今回の方法

circe-generic-extrasへの依存関係が必要です。

libraryDependencies ++= Seq(
  "io.circe" %% "circe-core",
  "io.circe" %% "circe-generic",
  "io.circe" %% "circe-generic-extras", // 追加
  "io.circe" %% "circe-parser"
).map(_ % circeVersion)

教えてもらったとおりですが、以下のような感じでできます。

import io.circe._
import io.circe.syntax._
import io.circe.generic.extras.auto._
import io.circe.generic.extras.Configuration

case class UserName(firstName: String, lastName: String)

implicit val jsonConfig: Configuration = Configuration.default.withSnakeCaseMemberNames

val userName = UserName(firstName = "Junichi", lastName = "Kato")
val json = userName.asJson

/*
{
  "first_name": "Junichi",
  "last_name": "Kato"
}
*/

ケースクラスごとにConfigurationを変えたい場合は、こんな感じでいけると思います。

import io.circe.generic.extras.semiauto._
import io.circe.generic.extras.Configuration

case class UserName(firstName: String, lastName: String)

object UserName {
  implicit val jsonConfig: Configuration = Configuration.default.withSnakeCaseMemberNames
  implicit val userNameDecoder: Decoder[UserName] = deriveDecoder
}
9
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
5