مرجع بنية لغة التعبير الشائعة (CEL) لخدمة SQL Connect

يغطّي هذا المرجع بنية لغة التعبير الشائعة (CEL) ذات الصلة بإنشاء تعبيرات للتوجيهات @auth(expr:) و@check(expr:) و@refresh(onMutationExecuted:).

تتوفّر معلومات مرجعية كاملة للغة التعبير الشائعة (CEL) في الـ مواصفات لغة التعبير الشائعة (CEL).

اختبار المتغيّرات التي يتم تمريرها في طلبات البحث وعمليات التعديل

تتيح لك بنية @auth(expr) الوصول إلى المتغيّرات واختبارها من طلبات البحث وعمليات التعديل.

على سبيل المثال، يمكنك تضمين متغيّر عملية، مثل $status، باستخدام vars.status.

mutation Update($id: UUID!, $status: Any) @auth(expr: "has(vars.status)")

البيانات المتاحة للتعبيرات: الطلب والاستجابة و"هذا"

يمكنك استخدام البيانات لما يلي:

  • التقييم باستخدام تعبيرات لغة التعبير الشائعة (CEL) في التوجيهَين @auth(expr:) و@check(expr:)
  • التعيين باستخدام تعبيرات الخادم، <field>_expr

يمكن أن تقيِّم تعبيرات لغة التعبير الشائعة (CEL) في @auth(expr:) و@check(expr:) و@refresh(onMutationExecuted:) ما يلي:

  • request.operationName
  • vars (اسم مستعار لـ request.variables)
  • auth (اسم مستعار لـ request.auth)

في عمليات التعديل، يمكنك الوصول إلى محتويات ما يلي وتعيينها:

  • response (للاطّلاع على النتائج الجزئية في منطق متعدّد الخطوات)

بالإضافة إلى ذلك، يمكن أن تقيِّم تعبيرات @check(expr:) ما يلي:

  • this (قيمة الحقل الحالي)
  • response (للاطّلاع على النتائج الجزئية في منطق متعدّد الخطوات)

وتحتوي تعبيرات @refresh(onMutationExecuted:) على الربط التالي:

  • mutation.variables
  • mutation.auth

ربط `request.operationName`

يخزِّن ربط request.operarationName نوع العملية، سواء كانت طلب بحث أو عملية تعديل.

ربط vars ‏ (request.vars)

يسمح ربط vars لتعبيراتك بالوصول إلى جميع المتغيّرات التي تم تمريرها في طلب البحث أو عملية التعديل.

يمكنك استخدام vars.<variablename> في تعبير كاسم مستعار لـ المؤهَّل بالكامل request.variables.<variablename>:

# The following are equivalent
mutation StringType($v: String!) @auth(expr: "vars.v == 'hello'")
mutation StringType($v: String!) @auth(expr: "request.variables.v == 'hello'")

ربط auth ‏ (request.auth)

Authentication تحدّد المستخدمين الذين يطلبون الوصول إلى بياناتك وتوفّر هذه المعلومات كربط يمكنك استخدامه في تعبيراتك.

في الفلاتر والتعبيرات، يمكنك استخدام auth كاسم مستعار لـ request.auth.

يحتوي ربط المصادقة على المعلومات التالية:

  • uid: معرّف مستخدم فريد تم تعيينه للمستخدم الذي يطلب الوصول
  • token: خريطة للقيم التي تم جمعها من خلال Authentication

لمزيد من التفاصيل حول محتويات auth.token، يُرجى الاطّلاع على البيانات في رموز المصادقة

ربط response

يحتوي ربط response على البيانات التي يجمعها الخادم ردًا على طلب بحث أو عملية تعديل أثناء تجميع هذه البيانات.

أثناء تقدُّم العملية، وعند اكتمال كل خطوة بنجاح، يحتوي response على بيانات الاستجابة من الخطوات التي تم إكمالها بنجاح.

يتم تنظيم ربط response وفقًا لشكل العملية المرتبطة به، بما في ذلك الحقول المتداخلة (المتعدّدة) وطلبات البحث المضمّنة (إن أمكن).

يُرجى العِلم أنّه عند الوصول إلى بيانات استجابة طلب البحث المضمّن، يمكن أن تحتوي الحقول على أي نوع من البيانات، استنادًا إلى البيانات المطلوبة في طلب البحث المضمّن. وعند الوصول إلى البيانات التي تعرضها حقول عمليات التعديل، مثل _insert و_delete، قد تحتوي على مفاتيح UUID وعدد عمليات الحذف والقيم الخالية (راجِع مرجع عمليات التعديل).

على سبيل المثال:

  • في عملية تعديل تحتوي على طلب بحث مضمّن، يحتوي ربط response على بيانات البحث في response.query.<fieldName>.<fieldName>....، في هذه الحالة، response.query.todoList وresponse.query.todoList.priority.
mutation CheckTodoPriority(
  $uniqueListName: String!
) {
  # This query is identified as `response.query`
  query @check(expr: "response.query.todoList.priority == 'high'", message: "This list is not for high priority items!") {
    # This field is identified as `response.query.todoList`
    todoList(where: { name: $uniqueListName }) {
      # This field is identified as `response.query.todoList.priority`
      priority
    }
  }
}
  • في عملية تعديل متعدّدة الخطوات، على سبيل المثال، مع حقول _insert متعدّدة، يحتوي ربط response على بيانات جزئية في response.<fieldName>.<fieldName>....، وفي هذه الحالة، response.todoList_insert.id.
mutation CreateTodoListWithFirstItem(
  $listName: String!,
  $itemContent: String!
) @transaction {
  # Step 1
  todoList_insert(data: {
    id_expr: "uuidV4()",
    name: $listName,
  })
  # Step 2:
  todo_insert(data: {
    listId_expr: "response.todoList_insert.id" # <-- Grab the newly generated ID from the partial response so far.
    content: $itemContent,
  })
}

ربط this

يتم تقييم الربط this إلى الحقل الذي تم إرفاق توجيه @check به. في حالة أساسية، يمكنك تقييم نتائج طلب البحث ذات القيمة الواحدة.

mutation UpdateMovieTitle (
  $movieId: UUID!,
  $newTitle: String!)
  @auth(level: USER)
  @transaction {
  # Step 1: Query and check
  query @redact {
    moviePermission( # Look up a join table called MoviePermission with a compound key.
      key: {movieId: $movieId, userId_expr: "auth.uid"}
    ) {
      # Check if the user has the editor role for the movie. `this` is the string value of `role`.
      # If the parent moviePermission is null, the @check will also fail automatically.
      role @check(expr: "this == 'editor'", message: "You must be an editor of this movie to update title")
    }
  }
  # Step 2: Act
  movie_update(id: $movieId, data: {
    title: $newTitle
  })
}

إذا ظهر الحقل الذي تم عرضه عدة مرات لأنّ أي عنصر من العناصر الرئيسية هو قائمة، يتم اختبار كل ظهور باستخدام this المرتبط بكل قيمة.

بالنسبة إلى أي مسار معيّن، إذا كان أحد العناصر الرئيسية null أو []، لن يتم الوصول إلى الحقل وسيتم تخطّي تقييم لغة التعبير الشائعة (CEL) لهذا المسار. بعبارة أخرى، لا يتم التقييم إلا عندما تكون قيمة this هي null أو غير null، ولكن لا تكون undefined أبدًا.

عندما يكون الحقل نفسه قائمة أو كائنًا، يتّبع this البنية نفسها (بما في ذلك جميع العناصر الفرعية المحدّدة في حالة الكائنات)، كما هو موضّح في المثال التالي.

mutation UpdateMovieTitle2($movieId: UUID!, $newTitle: String!) @auth(level: USER) @transaction {
  # Step 1: Query and check
  query {
    moviePermissions( # Now we query for a list of all matching MoviePermissions.
      where: {movieId: {eq: $movieId}, userId: {eq_expr: "auth.uid"}}
    # This time we execute the @check on the list, so `this` is the list of objects.
    # We can use the `.exists` macro to check if there is at least one matching entry.
    ) @check(expr: "this.exists(p, p.role == 'editor')", message: "You must be an editor of this movie to update title") {
      role
    }
  }
  # Step 2: Act
  movie_update(id: $movieId, data: {
    title: $newTitle
  })
}

بنية التعبير المعقّد

يمكنك كتابة تعبيرات أكثر تعقيدًا من خلال الجمع بين عوامل التشغيل && و||.

mutation UpsertUser($username: String!) @auth(expr: "(auth != null) && (vars.username == 'joe')")

يوضّح القسم التالي جميع عوامل التشغيل المتاحة.

عوامل التشغيل وأسبقية عوامل التشغيل

استخدِم الجدول التالي كمرجع لعوامل التشغيل وأسبقيتها المقابلة.

لنفترض أنّ لدينا تعبيرَين عشوائيَين a وb وحقل f وفهرس i.

عامل التشغيل الوصف التجميعية
a[i] a() a.f الفهرس، الاستدعاء، الوصول إلى الحقل من اليسار إلى اليمين
!a -a النفي الأحادي من اليمين إلى اليسار
a/b a%b a*b عوامل التشغيل المضاعفة من اليسار إلى اليمين
a+b a-b عوامل التشغيل الجمعية من اليسار إلى اليمين
a>b a>=b a<b a<=b عوامل التشغيل العلائقية من اليسار إلى اليمين
a in b الوجود في قائمة أو خريطة من اليسار إلى اليمين
type(a) == t مقارنة النوع، حيث يمكن أن يكون t قيمة منطقية أو عددًا صحيحًا أو عددًا عشريًا أو رقمًا أو سلسلة أو قائمة أو خريطة أو طابعًا زمنيًا أو مدة من اليسار إلى اليمين
a==b a!=b عوامل تشغيل المقارنة من اليسار إلى اليمين
a && b الشرط AND من اليسار إلى اليمين
a || b الشرط OR من اليسار إلى اليمين
a ? true_value : false_value التعبير الثلاثي من اليسار إلى اليمين

البيانات في رموز المصادقة

قد يحتوي الكائن auth.token على القيم التالية:

الحقل الوصف
email عنوان البريد الإلكتروني المرتبط بالحساب، إذا كان متوفّرًا
email_verified true إذا أكّد المستخدم أنّه يمكنه الوصول إلى عنوان email تؤكّد بعض الجهات المقدِّمة تلقائيًا عناوين البريد الإلكتروني التي تملكها.
phone_number رقم الهاتف المرتبط بالحساب، إذا كان متوفّرًا
name الاسم المعروض للمستخدم، إذا تم ضبطه
sub رقم تعريف المستخدم (UID) في Firebase وهو رقم فريد ضمن المشروع.
firebase.identities قاموس بجميع الهويات المرتبطة بحساب هذا المستخدم يمكن أن تكون مفاتيح القاموس أيًّا ممّا يلي: email وphone وgoogle.com وfacebook.com وgithub.com وtwitter.com. وقيم القاموس هي مصفوفات من المعرّفات الفريدة لكل جهة من جهات توفير الهوية المرتبطة بالحساب. على سبيل المثال، يحتوي auth.token.firebase.identities["google.com"][0] على أول رقم تعريف لمستخدم Google مرتبط بالحساب.
firebase.sign_in_provider جهة توفير تسجيل الدخول المستخدَمة للحصول على هذا الرمز المميّز يمكن أن تكون إحدى السلاسل التالية: custom أو password أو phone أو anonymous أو google.com أو facebook.com أو github.com أو twitter.com.
firebase.tenant رقم تعريف المستأجر المرتبط بالحساب، إذا كان متوفّرًا على سبيل المثال، tenant2-m6tyz

حقول إضافية في رموز تعريف JWT

يمكنك أيضًا الوصول إلى حقول auth.token التالية:

مطالبات الرمز المميّز المخصّص
alg خوارزمية "RS256"
iss جهة الإصدار عنوان البريد الإلكتروني لحساب الخدمة في مشروعك
sub الموضوع عنوان البريد الإلكتروني لحساب الخدمة في مشروعك
aud الجمهور "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat وقت الإصدار الوقت الحالي، بالثواني منذ بدء حقبة يونكس
exp وقت انتهاء الصلاحية الوقت، بالثواني منذ بدء حقبة يونكس، الذي تنتهي فيه صلاحية الرمز المميّز يمكن أن يكون بعد 3600 ثانية كحد أقصى من iat.
ملاحظة: لا يتحكّم هذا الإعداد إلا في الوقت الذي تنتهي فيه صلاحية الرمز المميّز المخصّص نفسه تنتهي صلاحيته. ولكن بعد تسجيل دخول المستخدم باستخدام signInWithCustomToken()، سيظل مسجِّلاً الدخول إلى الجهاز إلى أن يتم إبطال جلسته أو يسجّل المستخدم الخروج.
<claims> ‏ (اختياري) مطالبات مخصّصة اختيارية لتضمينها في الرمز المميّز، ويمكن الوصول إليها من خلال auth.token (أو request.auth.token) في التعبيرات على سبيل المثال، إذا أنشأت مطالبة مخصّصة adminClaim، يمكنك الوصول إليها باستخدام auth.token.adminClaim.