0Pricing
Scala for Backend Engineering & Functional Programming · درس

نقاط نهاية JSON

اجمع بين http4s وCirce

نقاط نهاية JSON درس مجاني في Scala for Backend Engineering & Functional Programming على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 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

اشتقاق برامج الترميز

باستخدام circe-generic، تشتق برامج الترميز تلقائيًا عبر deriveEncoder/deriveDecoder أو التعليمة التوضيحية @JsonCodec. وهي تطابق حقول case class مع مفاتيح JSON بحسب أسمائها.

يتطلب الاشتقاق توفر برامج ترميز لكل نوع من أنواع الحقول، بصورة递归ية.

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] لأي A لديه Encoder من circe. بعد ذلك، يحوّل 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 لديه Decoder من circe. بعد ذلك، يحلّل 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، اشتق برنامج الترميز باستخدام Configuration من circe-generic-extras، مثل snake_case، أو اكتب برنامج الترميز يدويًا باستخدام forProduct2.

يفصل ذلك عقد واجهة API عن التسمية الداخلية.

import io.circe.Encoder

implicit val e: Encoder[User] =
  Encoder.forProduct2("user_id", "full_name")(u => (u.id, u.name))

تشفير القوائم

توفر circe برامج ترميز لـ List وVector وOption وMap تلقائيًا بمجرد توفر برنامج ترميز للعناصر. لذلك تعمل إعادة مجموعة من العناصر مباشرةً.

تُشفَّر القائمة الفارغة إلى []، بينما تُشفَّر 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 وStream[F, A] من fs2 إلى إصدار مصفوفة JSON تدريجيًا.

يحافظ ذلك على ثبات استهلاك الذاكرة مع مجموعات النتائج الكبيرة، مستفيدًا من التحكم في التدفق العكسي في fs2.

import org.http4s.circe.streamJsonArrayEncoder

case GET -> Root / "feed" =>
  Ok(store.streamAll) // fs2.Stream[IO, Event]

تحقق سريع

تذكّر أي استيراد يتيح فك ترميز جسم JSON إلى case class.

مراجعة

ربطت JSON باستخدام http4s-circe: اشتققت برامج الترميز، واستوردت CirceEntityCodec، واستخدمت Ok(value) وreq.as[A] لإجراء إدخال وإخراج JSON كاملين.

وتعاملت مع القوائم، وأسماء الحقول المخصصة، وأخطاء JSON المنظمة، وحتى المصفوفات المتدفقة للحمولات الكبيرة.

الأسئلة الشائعة

هل درس «نقاط نهاية JSON» مجاني؟

نعم — نص درس «نقاط نهاية JSON» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 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 مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 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 يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. المسارات وHttpRoutes
  2. الطلبات والاستجابات
  3. نقاط نهاية JSON
  4. تقديم التطبيق
← العودة إلى Scala for Backend Engineering & Functional Programming