0Pricing
Scala for Backend Engineering & Functional Programming · レッスン

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)  // false

Cursorで移動する

ネストされたデータを読み取るには、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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. JSONを解析する
  2. ケースクラスにデコードする
  3. JSONにエンコードする
  4. カスタムCodec
← Scala for Backend Engineering & Functional Programmingに戻る