ปลายทาง JSON
ผสาน http4s เข้ากับ Circe
ปลายทาง JSON เป็นบทเรียน Scala for Backend Engineering & Functional Programming ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Scala for Backend Engineering & Functional Programming และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Scala for Backend Engineering & Functional Programming มีบทเรียนทั้งหมด 4 บทเรียน
JSON ผ่าน circe
http4s ผสานการทำงานกับ JSON ผ่านมอดูล http4s-circe ซึ่งเชื่อมตัวเข้ารหัสของ circe เข้ากับ EntityDecoder และ EntityEncoder โดย circe เป็นไลบรารี JSON เชิงฟังก์ชันสำหรับ Scala ที่ใช้งานกันเป็นมาตรฐานโดยพฤตินัย
คุณกำหนดอินสแตนซ์ Encoder และ Decoder สำหรับชนิดข้อมูลของคุณ แล้วให้ http4s จัดการรูปแบบข้อมูลบนเครือข่าย
// build.sbt
// "org.http4s" %% "http4s-circe" % http4sV
// "io.circe" %% "circe-generic" % circeVการสร้าง Codecs
เมื่อใช้ circe-generic คุณสามารถสร้าง codec โดยอัตโนมัติด้วย deriveEncoder/deriveDecoder หรือคำอธิบายประกอบ @JsonCodec ซึ่งจะจับคู่ฟิลด์ของคลาสแบบ case class กับคีย์ JSON ตามชื่อ
การสร้าง codec ต้องมี codec สำหรับชนิดของทุกฟิลด์ โดยทำซ้ำลงไปตามลำดับชั้น
import io.circe.generic.semiauto._
case class User(id: Int, name: String)
implicit val enc = deriveEncoder[User]
implicit val dec = deriveDecoder[User]EntityEncoder จาก circe
การนำเข้า org.http4s.circe.CirceEntityEncoder._ จะให้ EntityEncoder[F, A] แบบ implicit สำหรับ A ใด ๆ ที่มี circe Encoder จากนั้น Ok(user) จะทำการทำให้เป็นอนุกรมเป็น JSON พร้อมชนิดเนื้อหา application/json
ในตัวจัดการคำขอไม่จำเป็นต้องแปลงเป็น Json ด้วยตนเอง
import org.http4s.circe.CirceEntityEncoder._
HttpRoutes.of[IO] {
case GET -> Root / "me" => Ok(User(1, "Ada"))
}EntityDecoder จาก circe
ในทางกลับกัน org.http4s.circe.CirceEntityDecoder._ จะจัดเตรียม EntityDecoder[F, A] สำหรับ A ใด ๆ ที่มี circe Decoder จากนั้น req.as[User] จะวิเคราะห์เนื้อความ JSON
การนำเข้าทั้งสองรายการรวมอยู่ใน CirceEntityCodec._
import org.http4s.circe.CirceEntityDecoder._
case req @ POST -> Root / "users" =>
req.as[User].flatMap(u => Created(u))POST ที่ใช้ JSON อย่างครบถ้วน
เมื่อรวมการถอดรหัสและการเข้ารหัสเข้าด้วยกัน คุณจะได้จุดปลายทางสำหรับสร้างข้อมูลที่เป็นระเบียบ ได้แก่ วิเคราะห์ JSON ที่เข้ามาเป็นชนิดข้อมูลโดเมน เรียกใช้ตรรกะทางธุรกิจ แล้วเข้ารหัสผลลัพธ์กลับเป็น JSON
ความล้มเหลวในการถอดรหัสจะแสดงเป็น 422 หรือ 400 ผ่านตัวถอดรหัสของ circe
import org.http4s.circe.CirceEntityCodec._
case req @ POST -> Root / "users" =>
for {
in <- req.as[User]
out <- store.create(in)
res <- Created(out)
} yield resตัวแทรกสตริง json
สำหรับ JSON แบบเฉพาะกิจ ตัวแทรกสตริง json ของ circe จาก io.circe.literal จะสร้างค่า Json โดยตรงพร้อมค่าของ Scala ที่แทรกเข้ามา
เหมาะสำหรับการตอบกลับขนาดเล็กหรือข้อมูลทดสอบ โดยไม่ต้องสร้างคลาสแบบ case class
import io.circe.literal._
val body = json"""{ "status": "ok", "count": 3 }"""
Ok(body)ชื่อฟิลด์แบบกำหนดเอง
เมื่อคีย์ JSON แตกต่างจากชื่อฟิลด์ของ Scala ให้สร้าง codec ด้วย Configuration จาก circe-generic-extras เช่น snake_case หรือเขียน codec เองโดยใช้ forProduct2
วิธีนี้แยกสัญญา API ออกจากการตั้งชื่อภายใน
import io.circe.Encoder
implicit val e: Encoder[User] =
Encoder.forProduct2("user_id", "full_name")(u => (u.id, u.name))การเข้ารหัสรายการ
circe มี codec สำหรับ List, Vector, Option และ Map ให้อัตโนมัติเมื่อมี codec ของสมาชิกแล้ว ดังนั้นการส่งคืนคอลเลกชันจึงทำงานได้ทันที
รายการว่างจะถูกเข้ารหัสเป็น [] ส่วน None จะกลายเป็นคีย์ที่ไม่มีอยู่หรือเป็น null
import org.http4s.circe.CirceEntityEncoder._
case GET -> Root / "users" =>
store.all.flatMap(us => Ok(us)) // List[User] -> JSON arrayการตรวจสอบ JSON ที่ถอดรหัสแล้ว
การถอดรหัสทำให้คุณได้ค่าที่ถูกต้องตามไวยากรณ์ แต่การตรวจสอบความหมายเป็นหน้าที่ของคุณเอง ให้ตรวจสอบหลังจาก as และหยุดการทำงานพร้อมส่ง BadRequest เมื่อข้อมูลไม่ถูกต้อง
เก็บเงื่อนไขคงที่ของโดเมนไว้ในตัวสร้างอัจฉริยะที่คืนค่าเป็น Either เพื่อให้เข้าใจได้ชัดเจน
req.as[User].flatMap { u =>
if (u.name.nonEmpty) Created(u)
else BadRequest("name required")
}การตอบกลับข้อผิดพลาดเป็น JSON
ส่งข้อผิดพลาดที่มีโครงสร้างเป็น JSON เพื่อให้ไคลเอนต์วิเคราะห์ได้ กำหนดคลาสแบบ case class สำหรับข้อผิดพลาดพร้อมตัวเข้ารหัสของ circe แล้วส่งให้ตัวสร้างสถานะที่เกี่ยวข้อง
รูปแบบข้อผิดพลาดที่สอดคล้องกันทำให้ใช้งาน API ได้ง่ายขึ้นมาก
case class ApiError(code: String, message: String)
implicit val e = deriveEncoder[ApiError]
BadRequest(ApiError("E_NAME", "name required"))JSON แบบสตรีม
สำหรับคอลเลกชันขนาดใหญ่ คุณสามารถส่ง JSON แบบสตรีมแทนการเก็บทั้งหมดไว้ในหน่วยความจำ jsonEncoderOf ร่วมกับ fs2 Stream[F, A] จะส่งอาร์เรย์ JSON ออกมาอย่างต่อเนื่อง
วิธีนี้ทำให้การใช้หน่วยความจำคงที่แม้ชุดผลลัพธ์จะมีขนาดใหญ่ โดยอาศัยการควบคุมแรงดันย้อนกลับของ fs2
import org.http4s.circe.streamJsonArrayEncoder
case GET -> Root / "feed" =>
Ok(store.streamAll) // fs2.Stream[IO, Event]ตรวจสอบอย่างรวดเร็ว
ทบทวนว่าการนำเข้าใดทำให้สามารถถอดรหัสเนื้อความ JSON เป็นคลาสแบบ case class ได้
สรุป
คุณเชื่อมต่อ JSON ด้วย http4s-circe แล้ว โดยสร้าง codec นำเข้า CirceEntityCodec และใช้ Ok(value) / req.as[A] สำหรับการรับส่ง JSON อย่างครบถ้วน
คุณจัดการรายการ ชื่อฟิลด์แบบกำหนดเอง ข้อผิดพลาด JSON ที่มีโครงสร้าง และแม้แต่อาร์เรย์แบบสตรีมสำหรับข้อมูลขนาดใหญ่
คำถามที่พบบ่อย
บทเรียน “ปลายทาง JSON” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ปลายทาง JSON” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Scala for Backend Engineering & Functional Programming ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Scala for Backend Engineering & Functional Programming มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ปลายทาง JSON”
ผสาน http4s เข้ากับ Circe คุณปฏิบัติ Scala for Backend Engineering & Functional Programming ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Scala for Backend Engineering & Functional Programming หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Scala for Backend Engineering & Functional Programming บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “ปลายทาง JSON” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Scala for Backend Engineering & Functional Programming นี้ได้ไหม
ได้ บทเรียน Scala for Backend Engineering & Functional Programming ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ