JSONを解析する
テキストをJSONの値に変換します。
「JSONを解析する」はCoddyKit上の無料Scala for Backend Engineering & Functional Programmingレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはScala for Backend Engineering & Functional Programming学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Scala for Backend Engineering & Functional Programmingコースには全4レッスンが含まれています。
Circeを使う理由
Circeは、cats関数型エコシステム上に構築された、Scala向けの人気の高いJSONライブラリです。
型安全性と不変性を重視しており、パース時には例外をスローするのではなくEitherを返し、デコード時には型なしのマップではなく型付きの値を生成します。
このレッスンでは、生のJSONテキストをCirceのJsonモデルに変換する方法を扱います。
依存関係を追加する
Circeはいくつかのモジュールに分かれて提供されています。パースとコアモデルにはcirce-coreとcirce-parserが必要です。
circe-genericモジュールはcodecの自動導出を追加します。これは後のレッスンで扱います。
libraryDependencies ++= Seq(
"io.circe" %% "circe-core" % "0.14.6",
"io.circe" %% "circe-parser" % "0.14.6"
)parse関数
JSONを読み込むためのエントリーポイントはio.circe.parser.parseです。
この関数はStringを受け取り、Either[ParsingFailure, Json]を返します。左辺には構文エラーが入り、右辺にはパースされたツリーが入ります。
import io.circe.parser._
val result = parse("{\"name\": \"Ada\", \"age\": 36}")
// result: Either[ParsingFailure, Json]パース失敗への対処
parseはEitherを返すため、try/catchではなくパターンマッチやコンビネータを使って明示的にエラーを処理します。
ParsingFailureには、構文上の問題を説明する人間が読めるメッセージが含まれます。
parse("{ not valid }") match {
case Right(json) => println(json)
case Left(err) => println(s"Failed: ${err.message}")
}Jsonモデル
パースに成功した値はJsonです。これは、JSONの6種類(オブジェクト、配列、文字列、数値、真偽値、null)のいずれかを表す不変のツリーです。
isObjectなどの述語で調べたり、その形状に対してfoldを実行したりできます。
val json = parse("[1, 2, 3]").getOrElse(Json.Null)
println(json.isArray) // true
println(json.isObject) // falseCursorで移動する
ネストされたデータを読み取るには、Json値に対して.hcursorを呼び出します。HCursorはツリー内を移動できるzipperです。
downFieldを使うと、オブジェクトのキーの中へ移動できます。
val json = parse("{\"user\": {\"name\": \"Ada\"}}").toOption.get
val cursor = json.hcursor
val name = cursor.downField("user").downField("name").as[String]
// name: Either[DecodingFailure, String] = Right(Ada)asで値を取り出す
対象位置に移動したら、.as[A]で、その値を型Aとしてデコードします。
戻り値はEither[DecodingFailure, A]なので、型の不一致は例外ではなく値として報告されます。
val json = parse("{\"age\": 36}").toOption.get
val age = json.hcursor.downField("age").as[Int]
println(age) // Right(36)parseとdecode
生のJsonツリーを手動で調べたい場合はparseを使用します。
Stringから型付きの値Aへ一度に変換したい場合はdecode[A]を使用します。これはパースとデコードを組み合わせたものです。
import io.circe.parser.decode
val n: Either[io.circe.Error, Int] =
decode[Int]("42")
println(n) // Right(42)オプションのフィールド
実際のJSONでは、キーが存在しないことがよくあります。フィールドへ移動した後にCursorメソッドget[A]を使うと、キーがなければ失敗します。一方、getOrElseはデフォルト値を提供します。
Option[A]へデコードすると、存在しないフィールドやnullのフィールドはNoneとして扱われます。
val json = parse("{\"name\": \"Ada\"}").toOption.get
val nick = json.hcursor.get[Option[String]]("nickname")
println(nick) // Right(None)配列をパースする
List[A]やVector[A]を指定すれば、JSON配列をScalaのコレクションへ直接デコードできます。
Circeは各要素を変換し、いずれかの要素の型が正しくない場合はDecodingFailureで処理を途中終了します。
import io.circe.parser.decode
val xs = decode[List[Int]]("[1, 2, 3]")
println(xs) // Right(List(1, 2, 3))整形出力
任意のJson値は、.noSpacesでコンパクトなテキストに、.spaces2でインデント付きのテキストに戻せます。
パースしたデータを元の形式に戻せるほか、ログ出力やデバッグにも便利です。
val json = parse("{\"a\":1,\"b\":2}").toOption.get
println(json.noSpaces)
println(json.spaces2)確認問題
Circeによるパースについて理解度を確認しましょう。
まとめ
JSONテキストをCirceのモデルに変換する方法を学びました。parseはEither[ParsingFailure, Json]を返し、decode[A]は直接型付きの値を返します。
HCursorはdownFieldで移動でき、.as[A]で型付きの値を取り出せます。失敗は例外ではなく値として扱われます。
よくある質問
「JSONを解析する」レッスンは無料ですか?
はい。「JSONを解析する」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Scala for Backend Engineering & Functional Programmingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Scala for Backend Engineering & Functional Programmingコースには全4レッスンが含まれています。
「JSONを解析する」で何を学びますか?
テキストをJSONの値に変換します。 ブラウザで直接実行するハンズオンコードでScala for Backend Engineering & Functional Programmingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Scala for Backend Engineering & Functional Programmingを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのScala for Backend Engineering & Functional Programmingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「JSONを解析する」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このScala for Backend Engineering & Functional Programmingレッスンでコードを書いて実行できますか?
はい。すべてのScala for Backend Engineering & Functional Programmingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- JSONを解析する
- ケースクラスにデコードする
- JSONにエンコードする
- カスタムCodec