कस्टम रिज़ॉल्वर की मदद से, SQL Connect की सुविधाओं को बढ़ाना

कस्टम रिज़ॉल्वर लिखकर, Firebase SQL Connect को अन्य डेटा सोर्स के साथ काम करने के लिए बढ़ाया जा सकता है, इसके अलावा Cloud SQL. इसके बाद, एक ही क्वेरी या म्यूटेशन में कई डेटा सोर्स (Cloud SQL और आपके कस्टम रिज़ॉल्वर से मिले डेटा सोर्स) को जोड़ा जा सकता है.

"डेटा सोर्स" की अवधारणा फ़्लेक्सिबल है. इसमें ये शामिल हैं:

  • Cloud SQL के अलावा अन्य डेटाबेस, जैसे कि Cloud Firestore, MongoDB वगैरह.
  • स्टोरेज की सेवाएं, जैसे कि Cloud Storage, AWS S3 वगैरह.
  • एपीआई पर आधारित कोई भी इंटिग्रेशन, जैसे कि Stripe, SendGrid, Salesforce वगैरह.
  • कारोबारी नियम.

अतिरिक्त डेटा सोर्स के साथ काम करने के लिए, कस्टम रिज़ॉल्वर लिखने के बाद, आपकी SQL Connect क्वेरी और म्यूटेशन, उन्हें कई तरीकों से जोड़ सकते हैं. इससे ये फ़ायदे मिलते हैं:

  • आपके डेटा सोर्स के लिए, अनुमति देने वाली एक ही लेयर. उदाहरण के लिए, Cloud Storage में मौजूद फ़ाइलों के ऐक्सेस की अनुमति देना. इसके लिए, Cloud SQL में सेव किए गए डेटा का इस्तेमाल करें.
  • वेब, Android, और iOS के लिए, टाइप-सेफ़ क्लाइंट एसडीके.
  • ऐसी क्वेरी जो कई सोर्स से डेटा वापस करती हैं.
  • आपके डेटाबेस की स्थिति के आधार पर, फ़ंक्शन कॉल पर पाबंदी.

ज़रूरी शर्तें

अपने कस्टम रिज़ॉल्वर लिखने के लिए, आपको इनकी ज़रूरत होगी:

  • Firebase CLI का वर्शन 15.9.0 या इसके बाद का वर्शन
  • Firebase Functions SDK का वर्शन 7.1.0 या इसके बाद का वर्शन

इसके अलावा, आपको Firebase के लिए Cloud Functions का इस्तेमाल करके फ़ंक्शन लिखने के बारे में पता होना चाहिए. इसकी मदद से, अपने कस्टम रिज़ॉल्वर के लॉजिक को लागू किया जा सकेगा.

शुरू करने से पहले

SQL Connect का इस्तेमाल करने के लिए, आपके पास पहले से ही कोई प्रोजेक्ट सेट अप होना चाहिए.

अगर आपने अभी तक कोई प्रोजेक्ट सेट अप नहीं किया है, तो सेट अप करने के लिए, क्विकस्टार्ट गाइड में से किसी एक का पालन करें:

कस्टम रिज़ॉल्वर लिखना

कस्टम रिज़ॉल्वर लिखने के तीन हिस्से होते हैं: पहला, अपने कस्टम रिज़ॉल्वर के लिए स्कीमा तय करना; दूसरा, Cloud Functions का इस्तेमाल करके अपने रिज़ॉल्वर लागू करना; और तीसरा, क्वेरी और म्यूटेशन में अपने कस्टम रिज़ॉल्वर के फ़ील्ड का इस्तेमाल करना. ऐसा Cloud SQL या अन्य कस्टम रिज़ॉल्वर के साथ भी किया जा सकता है.

ऐसा करने का तरीका जानने के लिए, अगले कुछ सेक्शन में दिए गए चरणों का पालन करें. उदाहरण के लिए, मान लें कि आपके उपयोगकर्ताओं की सार्वजनिक प्रोफ़ाइल की जानकारी, Cloud SQL के बाहर सेव है.Cloud SQL इन उदाहरणों में, डेटा स्टोर की सटीक जानकारी नहीं दी गई है. हालांकि, यह Cloud Storage, MongoDB इंस्टेंस या कुछ और हो सकता है.

अगले सेक्शन में, कस्टम रिज़ॉल्वर को लागू करने का एक बुनियादी तरीका दिखाया जाएगा. इसकी मदद से, सार्वजनिक प्रोफ़ाइल की जानकारी को SQL Connectमें लाया जा सकता है.

अपने कस्टम रिज़ॉल्वर के लिए स्कीमा तय करना

  1. अपने Firebase प्रोजेक्ट की डायरेक्ट्री में, यह कमांड चलाएं:

    firebase init dataconnect:resolver

    Firebase CLI, आपसे आपके कस्टम रिज़ॉल्वर का नाम पूछेगा. साथ ही, यह भी पूछेगा कि TypeScript या JavaScript में, रिज़ॉल्वर को लागू करने के उदाहरण जनरेट करने हैं या नहीं. अगर इस गाइड में दिए गए निर्देशों का पालन किया जा रहा है, तो डिफ़ॉल्ट नाम स्वीकार करें और TypeScript के उदाहरण जनरेट करें.

    इसके बाद, टूल एक खाली dataconnect/schema_resolver/schema.gql फ़ाइल बनाएगा और dataconnect.yaml फ़ाइल में, आपके नए रिज़ॉल्वर का कॉन्फ़िगरेशन जोड़ेगा.

  2. schema.gql फ़ाइल को, GraphQL स्कीमा से अपडेट करें. इसमें उन क्वेरी और म्यूटेशन के बारे में बताया गया है जो आपका कस्टम रिज़ॉल्वर उपलब्ध कराएगा. उदाहरण के लिए, यहां एक कस्टम रिज़ॉल्वर का स्कीमा दिया गया है. इसकी मदद से, Cloud SQL के अलावा किसी अन्य डेटा स्टोर में सेव की गई, उपयोगकर्ता की सार्वजनिक प्रोफ़ाइल को वापस पाया जा सकता है और अपडेट किया जा सकता है:Cloud SQL

    # dataconnect/schema_resolver/schema.gql
    
    type PublicProfile {
      name: String!
      photoUrl: String!
      bioLine: String!
    }
    
    type Query {
      # This field will be backed by your Cloud Function.
      publicProfile(userId: String!): PublicProfile
    }
    
    type Mutation {
      # This field will be backed by your Cloud Function.
      updatePublicProfile(
        userId: String!, name: String, photoUrl: String, bioLine: String
      ): PublicProfile
    }
    

कस्टम रिज़ॉल्वर का लॉजिक लागू करना

इसके बाद, Cloud Functions का इस्तेमाल करके अपने रिज़ॉल्वर लागू करें. इसके लिए, आपको GraphQL सर्वर बनाना होगा. हालांकि, Cloud Functions में एक हेल्पर तरीका, onGraphRequest होता है. यह तरीका, GraphQL सर्वर बनाने से जुड़ी जानकारी को मैनेज करता है. इसलिए, आपको सिर्फ़ रिज़ॉल्वर का वह लॉजिक लिखना होगा जो आपके डेटा सोर्स को ऐक्सेस करता है.

  1. functions/src/index.ts फ़ाइल खोलें.

    ऊपर दी गई firebase init dataconnect:resolver कमांड चलाने पर, इस कमांड से Cloud Functions के सोर्स कोड की डायरेक्ट्री बन गई थी. साथ ही, index.ts में सैंपल कोड के साथ इसे शुरू किया गया था.

  2. ये परिभाषाएं जोड़ें:

    import {
      FirebaseContext,
      onGraphRequest,
    } from "firebase-functions/dataconnect/graphql";
    
    const opts = {
      // Points to the schema you defined earlier, relative to the root of your
      // Firebase project.
      schemaFilePath: "dataconnect/schema_resolver/schema.gql",
      resolvers: {
        query: {
          // This resolver function populates the data for the "publicProfile" field
          // defined in your GraphQL schema located at schemaFilePath.
          publicProfile(
            _parent: unknown,
            args: Record<string, unknown>,
            _contextValue: FirebaseContext,
            _info: unknown
          ) {
            const userId = args.userId;
    
            // Here you would use the user ID to retrieve the user profile from your data
            // store. In this example, we just return a hard-coded value.
    
            return {
              name: "Ulysses von Userberg",
              photoUrl: "https://example.com/profiles/12345/photo.jpg",
              bioLine: "Just a guy on a mountain. Ski fanatic.",
            };
          },
        },
        mutation: {
          // This resolver function updates data for the "updatePublicProfile" field
          // defined in your GraphQL schema located at schemaFilePath.
          updatePublicProfile(
            _parent: unknown,
            args: Record<string, unknown>,
            _contextValue: FirebaseContext,
            _info: unknown
          ) {
            const { userId, name, photoUrl, bioLine } = args;
    
            // Here you would update in your datastore the user's profile using the
            // arguments that were passed. In this example, we just return the profile
            // as though the operation had been successful.
    
            return { name, photoUrl, bioLine };
          },
        },
      },
    };
    
    export const resolver = onGraphRequest(opts);
    

इन बुनियादी उदाहरणों से पता चलता है कि रिज़ॉल्वर फ़ंक्शन को किस तरह का होना चाहिए. पूरी तरह से काम करने वाला कस्टम रिज़ॉल्वर बनाने के लिए, आपको टिप्पणी वाले सेक्शन में ऐसा कोड डालना होगा जो आपके डेटा सोर्स से डेटा पढ़ता और उसमें डेटा सेव करता है.

क्वेरी और म्यूटेशन में कस्टम रिज़ॉल्वर का इस्तेमाल करना

अपने कस्टम रिज़ॉल्वर का स्कीमा तय करने और उसके लॉजिक को लागू करने के बाद, SQL Connect की SQL Connect क्वेरी और म्यूटेशन में कस्टम रिज़ॉल्वर का इस्तेमाल किया जा सकता है. इसके बाद, इन कार्रवाइयों का इस्तेमाल करके, क्लाइंट एसडीके को अपने-आप जनरेट किया जा सकेगा. इसकी मदद से, Cloud SQL Cloud SQL, आपके कस्टम रिज़ॉल्वर या दोनों के कॉम्बिनेशन से मिले अपने सभी डेटा को ऐक्सेस किया जा सकेगा .

  1. dataconnect/example/queries.gql में, यह परिभाषा जोड़ें:

    query GetPublicProfile($id: String!)
        @auth(level: PUBLIC, insecureReason: "Anyone can see a public profile.") {
      publicProfile(userId: $id) {
        name
        photoUrl
        bioLine
      }
    }
    

    यह क्वेरी, आपके कस्टम रिज़ॉल्वर का इस्तेमाल करके, उपयोगकर्ता की सार्वजनिक प्रोफ़ाइल को वापस पाती है.

  2. dataconnect/example/mutations.gql में, यह परिभाषा जोड़ें:

    mutation SetPublicProfile(
      $id: String!, $name: String, $photoUrl: String, $bioLine: String
    ) @auth(expr: "vars.id == auth.uid") {
      updatePublicProfile(userId: $id, name: $name, photoUrl: $photoUrl, bioLine: $bioLine) {
        name
        photoUrl
        bioLine
      }
    }
    

    यह म्यूटेशन, डेटा स्टोर में प्रोफ़ाइल के नए डेटा को सेव करता है. इसके लिए, आपके कस्टम रिज़ॉल्वर का इस्तेमाल किया जाता है. ध्यान दें कि स्कीमा में, SQL Connect's @auth डायरेक्टिव का इस्तेमाल किया गया है, ताकि यह पक्का किया जा सके कि उपयोगकर्ता सिर्फ़ अपनी प्रोफ़ाइल अपडेट कर सकें. अपने डेटा स्टोर को SQL Connect के ज़रिए ऐक्सेस करने पर, आपको SQL Connect की सुविधाओं का फ़ायदा अपने-आप मिल जाता है. जैसे, यह सुविधा.

ऊपर दिए गए उदाहरणों में, SQL Connect उन कार्रवाइयों के बारे में बताया गया है जो आपके डेटा स्टोर से डेटा ऐक्सेस करती हैं. हालांकि, आपकी कार्रवाइयों में सिर्फ़ Cloud SQL या किसी एक कस्टम डेटा सोर्स से डेटा ऐक्सेस करने की पाबंदी नहीं है. एक से ज़्यादा सोर्स से डेटा को जोड़ने वाले, इस्तेमाल के कुछ और ऐडवांस उदाहरणों के लिए, उदाहरण सेक्शन देखें.

इससे पहले, अपने कस्टम रिज़ॉल्वर को काम करते हुए देखने के लिए, अगले सेक्शन पर जाएं.

अपने कस्टम रिज़ॉल्वर और कार्रवाइयों को डिप्लॉय करना

अपने SQL Connect स्कीमा में कोई भी बदलाव करने पर, आपको उन्हें डिप्लॉय करना होगा, ताकि वे लागू हो सकें. ऐसा करने से पहले, Cloud Functions का इस्तेमाल करके लागू किए गए कस्टम रिज़ॉल्वर के लॉजिक को डिप्लॉय करें:

firebase deploy --only functions

अब अपडेट किए गए स्कीमा और कार्रवाइयों को डिप्लॉय किया जा सकता है:

firebase deploy --only dataconnect

अपने SQL Connect स्कीमा में बदलाव करने के बाद, आपको क्लाइंट एसडीके भी जनरेट करने होंगे:

firebase dataconnect:sdk:generate

उदाहरण

इन उदाहरणों में, इस्तेमाल के कुछ और ऐडवांस उदाहरणों को लागू करने का तरीका बताया गया है. साथ ही, इनमें आम तौर पर होने वाली गड़बड़ियों से बचने का तरीका भी बताया गया है.

कस्टम रिज़ॉल्वर के ऐक्सेस की अनुमति देना, डेटा का इस्तेमाल करके Cloud SQL

कस्टम रिज़ॉल्वर का इस्तेमाल करके, अपने डेटा सोर्स को SQL Connect में इंटिग्रेट करने का एक फ़ायदा यह है कि ऐसी कार्रवाइयां लिखी जा सकती हैं जो डेटा सोर्स को जोड़ती हैं.

इस उदाहरण में, मान लें कि कोई सोशल मीडिया ऐप्लिकेशन बनाया जा रहा है. साथ ही, आपके पास एक म्यूटेशन है जिसे कस्टम रिज़ॉल्वर के तौर पर लागू किया गया है. यह म्यूटेशन, उपयोगकर्ता के दोस्त को एक नड्ज ईमेल भेजता है. ऐसा तब होता है, जब दोस्त ने कुछ समय से उपयोगकर्ता के साथ कोई इंटरैक्शन न किया हो.

नड्ज की सुविधा लागू करने के लिए, ऐसा कस्टम रिज़ॉल्वर बनाएं जिसका स्कीमा इस तरह का हो:

# A GraphQL server must define a root query type per the spec.
type Query {
  unused: String
}

type Mutation {
  sendEmail(id: String!, content: String): Boolean
}

इस परिभाषा के लिए, Cloud Function का इस्तेमाल किया जाता है. जैसे, यह Cloud Function:

import {
  FirebaseContext,
  onGraphRequest,
} from "firebase-functions/dataconnect/graphql";

const opts = {
  schemaFilePath: "dataconnect/schema_resolver/schema.gql",
  resolvers: {
    mutation: {
      sendEmail(
        _parent: unknown,
        args: Record<string, unknown>,
        _contextValue: FirebaseContext,
        _info: unknown
      ) {
        const { id, content } = args;

        // Look up the friend's email address and call the cloud service of your
        // choice to send the friend an email with the given content.

       return true;
      },
    },
  },
};

export const resolver = onGraphRequest(opts);

sendEmail कस्टम रिज़ॉल्वर का इस्तेमाल करने से पहले, यह पक्का करना ज़रूरी है कि ईमेल पाने वाला व्यक्ति, उपयोगकर्ता की दोस्त सूची में शामिल हो. ऐसा इसलिए, क्योंकि ईमेल भेजने में आपको पैसे खर्च करने पड़ते हैं. साथ ही, इसका गलत इस्तेमाल भी किया जा सकता है.

मान लें कि आपके ऐप्लिकेशन में, दोस्त सूची का डेटा Cloud SQL में सेव है:

type User @table {
  id: String! @default(expr: "auth.uid")
  acceptNudges: Boolean! @default(value: false)
}

type UserFriend @table(key: ["user", "friend"]) {
  user: User!
  friend: User!
}

एक ऐसा म्यूटेशन लिखा जा सकता है जो ईमेल भेजने के लिए कस्टम रिज़ॉल्वर का इस्तेमाल करने से पहले, Cloud SQL से क्वेरी करता है. इससे यह पक्का किया जा सकेगा कि भेजने वाला व्यक्ति , पाने वाले की दोस्त सूची में शामिल है या नहीं:

# Send a "nudge" to a friend as a reminder. This will only let the user send a
# nudge if $friendId is in the user's friends list.
mutation SendNudge($friendId: String!) @auth(level: USER_EMAIL_VERIFIED) {
  # Step 1: Query and check
  query @redact {
    userFriend(
      key: {userId_expr: "auth.uid", friendId: $friendId}
    # This checks that $friendId is in the user's friends list.
    ) @check(expr: "this != null", message: "You must be friends to nudge") {
      friend {
        # This checks that the friend is accepting nudges.
        acceptNudges @check(expr: "this == true", message: "Not accepting nudges")
      }
    }
  }
  # Step 2: Act
  sendEmail(id: $friendId, content: "You've been nudged!")
}

इसके अलावा, इस उदाहरण से यह भी पता चलता है कि कस्टम रिज़ॉल्वर के संदर्भ में, डेटा सोर्स में डेटाबेस और इसी तरह के अन्य सिस्टम के अलावा, अन्य संसाधन भी शामिल हो सकते हैं. इस उदाहरण में, डेटा सोर्स, क्लाउड ईमेल भेजने की सेवा है.

म्यूटेशन का इस्तेमाल करके, क्रम से लागू होने की सुविधा पक्का करना

डेटा सोर्स को जोड़ते समय, अक्सर यह पक्का करना ज़रूरी होता है कि एक डेटा सोर्स के लिए किया गया अनुरोध पूरा हो जाए. इसके बाद ही, किसी दूसरे डेटा सोर्स के लिए अनुरोध किया जाए. उदाहरण के लिए, मान लें कि आपके पास एक ऐसी क्वेरी है जो एआई एपीआई का इस्तेमाल करके, मांग पर वीडियो को डाइनैमिक तरीके से ट्रांसक्रिप्ट करती है. इस तरह का एपीआई कॉल महंगा हो सकता है. इसलिए, आपको कॉल को कुछ शर्तों के तहत गेट करना होगा. जैसे, उपयोगकर्ता के पास वीडियो का मालिकाना हक हो या उपयोगकर्ता ने आपके ऐप्लिकेशन में किसी तरह के प्रीमियम क्रेडिट खरीदे हों.

इसे हासिल करने की पहली कोशिश कुछ इस तरह की हो सकती है:

# This won't work as expected.
query BrokenTranscribeVideo($videoId: UUID!) @auth(level: USER_EMAIL_VERIFIED) {
  # Step 1: Check quota using SQL.
  # Verify the user owns the video and has "pro" status or credits.
  checkQuota: query @redact {
    video(id: $videoId)
    {
      user @check(expr: "this.id == auth.uid && this.hasCredits == true", message: "Unauthorized access") {
        id
        hasCredits
      }
    }
  }

  # Step 2: Trigger expensive compute
  # Only triggers if Step 1 succeeds? No! This won't work because query field
  # execution order is not guaranteed.
  triggerTranscription: query {
    # For example, might call Vertex AI or Transcoder API.
    startVideoTranscription(videoId: $videoId)
  }
}

यह तरीका काम नहीं करेगा, क्योंकि क्वेरी फ़ील्ड के लागू होने के क्रम की कोई गारंटी नहीं होती. GraphQL सर्वर, एक साथ कई कार्रवाइयां करने के लिए, किसी भी क्रम में फ़ील्ड को हल कर सकता है . दूसरी ओर, म्यूटेशन के फ़ील्ड हमेशा क्रम से हल किए जाते हैं, क्योंकि GraphQL सर्वर को उम्मीद होती है कि म्यूटेशन के कुछ फ़ील्ड को हल करने पर, साइड इफ़ेक्ट हो सकते हैं.

भले ही, उदाहरण के तौर पर दी गई कार्रवाई के पहले चरण में साइड इफ़ेक्ट न हों, लेकिन कार्रवाई को म्यूटेशन के तौर पर तय किया जा सकता है. ऐसा इसलिए, ताकि म्यूटेशन के फ़ील्ड क्रम से हल किए जा सकें:

# By using a mutation, we guarantee the SQL check happens FIRST.
mutation TranscribeVideo($videoId: UUID!) @auth(level: USER_EMAIL_VERIFIED) {
  # Step 1: Check quota using SQL.
  # Verify the user owns the video and has "pro" status or credits.
  checkQuota: query @redact {
    video(id: $videoId)
    {
      user @check(expr: "this.id == auth.uid && this.hasCredits == true", message: "Unauthorized access") {
        id
        hasCredits
      }
    }
  }

  # Step 2: Trigger expensive compute
  # This Cloud Function will ONLY trigger if Step 1 succeeds.
  triggerTranscription: query {
    # For example, might call Vertex AI or Transcoder API.
    startVideoTranscription(videoId: $videoId)
  }
}

सीमाएं

कस्टम रिज़ॉल्वर की सुविधा, एक्सपेरिमेंट के तौर पर पब्लिक प्रीव्यू के तौर पर रिलीज़ की गई है. अभी इस सुविधा के साथ काम करने में ये सीमाएं हैं:

कस्टम रिज़ॉल्वर के आर्ग्युमेंट में, CEL एक्सप्रेशन का इस्तेमाल नहीं किया जा सकता

कस्टम रिज़ॉल्वर के आर्ग्युमेंट में, CEL एक्सप्रेशन का डाइनैमिक तरीके से इस्तेमाल नहीं किया जा सकता. उदाहरण के लिए, यह काम नहीं करेगा:

mutation UpdateMyProfile($newName: String!) @auth(level: USER) {
  updateMongoDocument(
    collection: "profiles"
    # This isn't supported:
    id_expr: "auth.uid"
    update: { name: $newName }
  )
}

इसके बजाय, स्टैंडर्ड वैरिएबल (उदाहरण के लिए, $authUid) पास करें और सुरक्षित तरीके से मूल्यांकन किए गए @auth(expr: ...) डायरेक्टिव का इस्तेमाल करके, ऑपरेशन के लेवल पर उनकी पुष्टि करें.

mutation UpdateMyProfile(
  $newName: String!, $authUid: String!
) @auth(expr: "vars.authUid == auth.uid") {
  updateMongoDocument(
    collection: "profiles"
    id: $authUid
    update: { name: $newName }
  )
}

एक और तरीका यह है कि अपने सभी लॉजिक को कस्टम रिज़ॉल्वर में ले जाएं और Cloud Functions से अपने सभी डेटा ऑपरेशन पूरे करें.

उदाहरण के लिए, इस उदाहरण पर विचार करें. यह फ़िलहाल काम नहीं करेगा:

mutation BrokenForwardToEmail($chatMessageId: UUID!) @auth(level: USER_EMAIL_VERIFIED) {
  query {
    chatMessage(id: $chatMessageId) {
      content
    }
  }
  sendEmail(
    title: "Forwarded Chat Message"
    to_expr: "auth.token.email" # Not supported.
    content_expr: "response.query.chatMessage.content" # Not supported.
  )
}

इसके बजाय, Cloud SQL क्वेरी और ईमेल सेवा के लिए किए गए कॉल, दोनों को एक म्यूटेशन फ़ील्ड में ले जाएं. इसके लिए, किसी फ़ंक्शन का इस्तेमाल करें:

mutation ForwardToEmail($chatMessageId: UUID!) @auth(level: USER_EMAIL_VERIFIED) {
  forwardChatToEmail(
    chatMessageId: $chatMessageId
  )
}

अपने डेटाबेस के लिए, एडमिन एसडीके जनरेट करें और Cloud SQL क्वेरी करने के लिए, इसका इस्तेमाल फ़ंक्शन में करें:

const opts = {
 schemaFilePath: "dataconnect/schema_resolver/schema.gql",
 resolvers: {
   query: {
     async forwardToEmail(
       _parent: unknown,
       args: Record<string, unknown>,
       _contextValue: FirebaseContext,
       _info: unknown
     ) {
       const chatMessageId = args.chatMessageId as string;

       let decodedToken;
       try {
         decodedToken = await getAuth().verifyIdToken(_contextValue.auth.token ?? "");
       } catch (error) {
         return false;
       }

       const email = decodedToken.email;
       if (!email) {
         return false;
       }

       const response = await getChatMessage({chatMessageId});
       const messageContent = response.data.chatMessage?.content;

       // Here you call the cloud service of your choice to send the email with
       // the message content.

       return true;
     }
   },
 },
};
export const resolver = onGraphRequest(opts);

कस्टम रिज़ॉल्वर के पैरामीटर में, इनपुट ऑब्जेक्ट टाइप का इस्तेमाल नहीं किया जा सकता

कस्टम रिज़ॉल्वर, GraphQL के जटिल इनपुट टाइप स्वीकार नहीं करते. पैरामीटर, बुनियादी स्केलर टाइप (String, Int, Date, Any वगैरह) और Enum होने चाहिए.

input PublicProfileInput {
  name: String!
  photoUrl: String!
  bioLine: String!
}

type Mutation {
  # Not supported:
  updatePublicProfile(userId: String!, profile: PublicProfileInput): PublicProfile

  # OK:
  updatePublicProfile(userId: String!, name: String, photoUrl: String, bioLine: String): PublicProfile
}

कस्टम रिज़ॉल्वर, एसक्यूएल ऑपरेशन से पहले इस्तेमाल नहीं किए जा सकते

म्यूटेशन में, स्टैंडर्ड एसक्यूएल ऑपरेशन से पहले कस्टम रिज़ॉल्वर का इस्तेमाल करने पर, गड़बड़ी होती है. एसक्यूएल पर आधारित सभी ऑपरेशन, कस्टम रिज़ॉल्वर के कॉल से पहले दिखने चाहिए.

कोई लेन-देन नहीं (@transaction)

कस्टम रिज़ॉल्वर को, स्टैंडर्ड एसक्यूएल ऑपरेशन के साथ @transaction ब्लॉक में रैप नहीं किया जा सकता. अगर एसक्यूएल इंसर्ट के सफल होने के बाद, रिज़ॉल्वर के लिए इस्तेमाल किया गया Cloud Function काम नहीं करता है, तो डेटाबेस अपने-आप रोल बैक नहीं होगा.

एसक्यूएल और किसी अन्य डेटा सोर्स के बीच, लेन-देन की सुरक्षा हासिल करने के लिए, एसक्यूएल ऑपरेशन के लॉजिक को Cloud Function में ले जाएं. साथ ही, पुष्टि और रोलबैक को मैनेज करने के लिए, एडमिन एसडीके या सीधे एसक्यूएल कनेक्शन का इस्तेमाल करें.