قم بدمج القيم المؤجلة المتعددة في نوع مؤجل جديد في Sangria ، تنفيذ GraphQL

0

لدينا نقطتا نهاية (مكالمات خلفية) تعرضان أنواع بيانات مختلفة ولكنها ذات صلة XData و YData . إذا مثيل XData موجود بمعرف 1 ، ثم يجب أن يكون هناك مثيل لـ YData بنفس المعرف 1 .

لقد أنشأنا أداة جلب لكل نوع بيانات xFetcher و yFetcher . يتم استخدام هذه الجلب بشكل منفصل في استعلام GraphQL الخاص بنا لجلب البيانات من نقطتي النهاية ، ولكن بالنسبة لبعض حالات الاستخدام ، نريد دمج البيانات المستردة من كل منهما باستخدام معرف محدد ، على سبيل المثال ، 1 . قد لا تكون هذه المجموعة ملحقة قائمة بسيطة ، كما هو موضح في المثال أدناه.

مثل XData و YData يتم أيضًا الاستعلام عنها بشكل منفصل في أجزاء أخرى من الاستعلام ، ولا يمكننا ببساطة دمج هذين المحللين في حل واحد ، ونحن نحاول تجنب إجراء مكالمات متعددة إلى نفس نقطة النهاية إن أمكن.

لقد قمت بإنشاء مثال مبسط لحالة الاستخدام هذه. كيف يمكننا إرجاع قيمة مؤجلة واحدة تجمع بين البيانات المستردة من جلبين؟

case class Ctx()
case class XData(id: Int, a: Seq[String], b: String)
case class YData(id: Int, a: Seq[String], c: String)
case class Data(id: Int)

val xFetcher = Fetcher((ctx: Ctx, ids: Seq[Int]) => Future {
  ids.map(id => XData(1, Seq.empty, "")) // Back end call to (endpoint X)
})(HasId(_.id))

val yFetcher = Fetcher((ctx: Ctx, ids: Seq[Int]) => Future {
  ids.map(id => YData(1, Seq.empty, "")) // Back end call to (endpoint Y)
})(HasId(_.id))

val GData = deriveObjectType[Ctx, Data](
  AddFields(
    Field("a",
      ListType(StringType),
      resolve = ctx => getA(ctx))
  )
)

def getA(ctx: Context[Ctx, Data]) = {
  val id = ctx.value.id

  // Here I should also get an instance of `YData` and return the
  // combination of the sequences `a` in both instances (xData, yData)
  val xData: XData = ??? //getDeferredXData()
  val yData: YData = ??? //getDeferredYData()
  val desiredOutput = xData.a ++ yData.a

  // I can get `a` from one instance but not both of them together
  DeferredValue({
    val xData = xFetcher.defer(id)
    // val yData = yFetcher.defer(id)
    // How can we combine both into one deferred value?
    xData
  }).mapWithErrors { data => (data.a, Vector.empty) }
}

لم أستخدم Sangria كثيرًا ، لذا يرجى إعفاء أي معلومات غير واضحة تتعلق deferred resolvers أو fetchers

1 إجابة

1
افضل جواب

يبدو وصف السيناريو الخاص بك مشابهًا تمامًا لهذه المشكلة:

إضافة عناصر إضافية إلى ذاكرة التخزين المؤقت لكل طلب

تم تنفيذه بالفعل ، ولكن لم يتم إصداره بعد.

أيضًا ، إذا كان من المقبول التحميل دائمًا XData و YData معًا ، يمكنك بعد ذلك تحديد جلب للصف (XData, YData) . ثم في المحلل ، يمكنك استخراج كائن مطلوب من المجموعة. شيء من هذا القبيل:

DeferredValue(fetcher.defer(id)).map {case (xData, yData) ⇒ xData}
:مؤلف
فوق
قائمة طعام