Scala for Backend Engineering & Functional Programming · บทเรียน

คำขอและการตอบกลับ

อ่านข้อมูลนำเข้าและส่งคืนข้อมูลส่งออก

บทเรียน 2 จาก 413 ขั้นตอน

คำขอและการตอบกลับ เป็นบทเรียน Scala for Backend Engineering & Functional Programming ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Scala for Backend Engineering & Functional Programming และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Scala for Backend Engineering & Functional Programming มีบทเรียนทั้งหมด 4 บทเรียน

คำขอในฐานะค่า

ใน http4s Request[F] เป็นค่าที่เปลี่ยนแปลงไม่ได้ ซึ่งเก็บเมธอด URI ส่วนหัว เวอร์ชัน HTTP และเนื้อหาแบบสตรีมไว้ คุณตรวจสอบค่าเหล่านี้ด้วย accessor แบบบริสุทธิ์ และไม่แก้ไขค่าเดิมโดยตรง

หากต้องการเปลี่ยนคำขอ ให้สร้างสำเนาผ่าน withHeaders, withUri หรือตัวประกอบอื่นที่คล้ายกัน

val r: Request[IO] = Request[IO](
  method = Method.GET,
  uri = uri"/health"
)

เนื้อหาแบบสตรีม

เนื้อหาของคำขอหรือการตอบสนองคือ fs2.Stream[F, Byte] ซึ่งจะถูกประมวลผลแบบขี้เกียจและมีเอฟเฟกต์ ดังนั้นข้อมูลขนาดใหญ่จึงไม่จำเป็นต้องอยู่ในหน่วยความจำทั้งหมด

โดยทั่วไปคุณไม่ต้องจัดการไบต์ดิบ เพราะ EntityDecoder จะจัดการการถอดรหัสให้

// raw access (rarely needed)
val bytes: fs2.Stream[IO, Byte] = request.body

การถอดรหัสเนื้อหา

EntityDecoder[F, A] รู้วิธีแปลงสตรีมเนื้อหาให้เป็น A เรียก req.as[A] เพื่อถอดรหัส ซึ่งจะส่งคืน F[A] และทำให้เอฟเฟกต์ล้มเหลวหากเนื้อหาไม่ถูกต้อง

มี decoder ในตัวสำหรับ String ส่วน decoder ที่มีความสามารถมากขึ้นมาจากโมดูล JSON

HttpRoutes.of[IO] {
  case req @ POST -> Root / "echo" =>
    req.as[String].flatMap(body => Ok(body))
}

การผูกคำขอ

หากต้องการเข้าถึงออบเจ็กต์คำขอภายในกรณี ให้ผูกด้วย @ ในที่นี้ req ใช้ตั้งชื่อให้คำขอทั้งก้อน ขณะที่รูปแบบยังคงจับคู่เมธอดและเส้นทาง

หากไม่ใช้ตัวผูก คุณจะมีเพียงส่วนที่แยกออกมา และไม่สามารถอ่านเนื้อหาหรือส่วนหัวได้

HttpRoutes.of[IO] {
  case req @ PUT -> Root / "name" =>
    req.as[String].flatMap(n => Ok(s"set $n"))
}

การอ่านส่วนหัว

ส่วนหัวอยู่ใน request.headers ใช้ headers.get[H] กับโมเดลส่วนหัวที่ระบุชนิด หรือใช้ headers.get(CIString("X-Custom")) สำหรับชื่อที่กำหนดเอง

ส่วนหัวที่ระบุชนิด เช่น Authorization และ Content-Type จะวิเคราะห์และตรวจสอบค่าของตนให้คุณ

import org.http4s.headers.Authorization

val auth: Option[Authorization] =
  request.headers.get[Authorization]

การสร้างการตอบสนอง

ตัวสร้างการตอบสนองของ DSL เช่น Ok, Created และ NotFound เป็นฟังก์ชันที่ส่งคืน F[Response[F]] การส่งอาร์กิวเมนต์จะกำหนดเนื้อหาผ่าน EntityEncoder

ตัวสร้างแต่ละตัวสอดคล้องกับรหัสสถานะ ดังนั้น Created(...) จะให้ผลเป็น 201

Ok("all good")          // 200
Created("made it")      // 201
NotFound("missing")     // 404

กำหนดรหัสสถานะโดยตรง

สำหรับสถานะที่ไม่มีตัวสร้างอำนวยความสะดวก หรือเมื่อต้องการปรับแต่ง ให้สร้าง Response[F] ด้วย Status ที่ระบุอย่างชัดเจน แล้วต่อด้วย withEntity

วิธีนี้ทำให้ควบคุมสถานะ ส่วนหัว และเนื้อหาได้อย่างเต็มที่ใน expression เดียว

import org.http4s.{Response, Status}

Response[IO](Status.Accepted)
  .withEntity("queued")
  .pure[IO]

การเข้ารหัสเนื้อหา

EntityEncoder[F, A] ทำให้ค่าเป็นอนุกรมลงในเนื้อหาการตอบสนองและกำหนด Content-Type ให้ด้วย มี encoder สำหรับ String และไบต์มาให้ในตัว ส่วน encoder ของ JSON มาจาก circe

เมื่อคุณส่งค่าให้กับ Ok(value) http4s จะค้นหา encoder แบบ implicit ให้โดยอัตโนมัติ

// String encoder is implicit; sets text/plain
val resp: IO[Response[IO]] = Ok("plain text body")

การกำหนดส่วนหัวการตอบสนอง

เพิ่มส่วนหัวโดยส่งเป็นอาร์กิวเมนต์เพิ่มเติมให้กับตัวสร้าง หรือใช้ .map(_.putHeaders(...)) ต่อกับเอฟเฟกต์การตอบสนอง

โมเดลส่วนหัวที่ระบุชนิดช่วยรับรองว่าค่าจะมีรูปแบบถูกต้อง เช่น ส่วนหัว Location ของ 201 Created

import org.http4s.headers.Location

Created("ok").map(_.putHeaders(
  Location(uri"/items/42")
))

การจัดการความล้มเหลวในการถอดรหัส

req.as[A] จะทำให้เอฟเฟกต์ F ล้มเหลวเมื่อไม่สามารถถอดรหัสเนื้อหาได้ ใช้ req.attemptAs[A].value เพื่อรับค่า F[Either[DecodeFailure, A]] แล้วตอบกลับด้วย 400 เมื่ออยู่ในฝั่งซ้าย

วิธีนี้ทำให้การจัดการอินพุตที่ไม่ถูกต้องมีความชัดเจนและครอบคลุมทุกกรณี

req.attemptAs[String].value.flatMap {
  case Right(b) => Ok(b)
  case Left(_)  => BadRequest("bad body")
}

คุกกี้และการเปลี่ยนเส้นทาง

กำหนดคุกกี้ด้วย response.addCookie(ResponseCookie(name, value)) สำหรับการเปลี่ยนเส้นทาง ให้ใช้ตัวสร้าง 3xx และส่วนหัว Location

SeeOther(Location(uri)) ดำเนินการแบบ 303 ซึ่งเป็นการตอบสนองหลังส่งข้อมูลแล้วเปลี่ยนเส้นทางเพื่อเรียกดูตามรูปแบบที่เหมาะสม

import org.http4s.headers.Location

SeeOther(Location(uri"/login"))
  .map(_.addCookie("sid", "abc123"))

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ลองพิจารณาการถอดรหัสเนื้อหาอย่างปลอดภัย

สรุปทบทวน

คำขอและการตอบกลับเป็นค่าแบบไม่เปลี่ยนแปลง โดยมีเนื้อความแบบสตรีมจาก fs2 คุณถอดรหัสด้วย as/attemptAs ผ่าน EntityDecoder และเข้ารหัสด้วย EntityEncoder

ตัวสร้างใช้กำหนดรหัสสถานะ ส่วนส่วนหัวแบบมีชนิดยังคงปลอดภัย และคุกกี้กับการเปลี่ยนเส้นทางก็เป็นเพียงการแปลงการตอบกลับ

เริ่มต้นได้ฟรี

เรียนรู้ Scala ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
39
บทเรียน
143

คำถามที่พบบ่อย

บทเรียน “คำขอและการตอบกลับ” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “คำขอและการตอบกลับ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Scala for Backend Engineering & Functional Programming ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Scala for Backend Engineering & Functional Programming มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “คำขอและการตอบกลับ”

อ่านข้อมูลนำเข้าและส่งคืนข้อมูลส่งออก คุณปฏิบัติ Scala for Backend Engineering & Functional Programming ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Scala for Backend Engineering & Functional Programming หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Scala for Backend Engineering & Functional Programming บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “คำขอและการตอบกลับ” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Scala for Backend Engineering & Functional Programming นี้ได้ไหม

ได้ บทเรียน Scala for Backend Engineering & Functional Programming ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. เส้นทางและ HttpRoutes
  2. คำขอและการตอบกลับ
  3. ปลายทาง JSON
  4. ให้บริการแอปพลิเคชัน
← กลับไปที่ Scala for Backend Engineering & Functional Programming