Data Connect म्यूटेशन लागू करना

Firebase Data Connect की मदद से, Google Cloud SQL से मैनेज किए जा रहे PostgreSQL इंस्टेंस के लिए कनेक्टर बनाए जा सकते हैं. ये कनेक्टर, आपके स्कीमा से डेटा का इस्तेमाल करने के लिए, क्वेरी और म्यूटेशन के कॉम्बिनेशन होते हैं.

शुरू करने के लिए गाइड में, PostgreSQL के लिए, फ़िल्म की समीक्षा करने वाले ऐप्लिकेशन का स्कीमा जोड़ा गया है.

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

  • डिप्लॉय किए जा सकने वाले म्यूटेशन, ऐसे म्यूटेशन होते हैं जिन्हें कनेक्टर में क्लाइंट ऐप्लिकेशन से कॉल करने के लिए लागू किया जाता है. ये म्यूटेशन, आपके तय किए गए एपीआई एंडपॉइंट के साथ काम करते हैं. Data Connect, इन म्यूटेशन में पुष्टि और अनुमति को इंटिग्रेट करता है. साथ ही, आपके एपीआई के आधार पर क्लाइंट SDK टूल जनरेट करता है.
  • एड-हॉक एडमिनिस्ट्रेटिव म्यूटेशन, खास एनवायरमेंट से चलाए जाते हैं, ताकि टेबल में जानकारी भरी जा सके और उन्हें मैनेज किया जा सके. इन्हें Firebase कंसोल में बनाया और चलाया जा सकता है. इसके लिए, Firebase Admin SDK का इस्तेमाल करके, ऐक्सेस लेवल वाले एनवायरमेंट का इस्तेमाल करें. साथ ही, हमारे Data Connect VS Code एक्सटेंशन का इस्तेमाल करके, लोकल डेवलपमेंट एनवायरमेंट में भी इन्हें बनाया और चलाया जा सकता है.

इस गाइड में, डिप्लॉय किए जा सकने वाले म्यूटेशन के बारे में ज़्यादा जानकारी दी गई है.

Data Connect म्यूटेशन की सुविधाएं

Data Connect की मदद से, PostgreSQL डेटाबेस में बुनियादी बदलाव, उन सभी तरीकों से किए जा सकते हैं जिनकी उम्मीद आपने की होगी:

  • CRUD ऑपरेशन करना
  • लेन-देन की मदद से, कई चरणों वाले ऑपरेशन मैनेज करना

हालांकि, GraphQL में Data Connect के एक्सटेंशन की मदद से, तेज़ और ज़्यादा असरदार ऐप्लिकेशन के लिए बेहतर म्यूटेशन लागू किए जा सकते हैं:

  • रिकॉर्ड पर बार-बार की जाने वाली कार्रवाइयों को आसान बनाने के लिए, कई कार्रवाइयों से मिले की स्केलर का इस्तेमाल करें
  • सर्वर से मिलने वाली कार्रवाइयों के साथ डेटा को पॉप्युलेट करने के लिए, सर्वर वैल्यू का इस्तेमाल करना
  • डेटा को खोजने के लिए, कई चरणों वाले म्यूटेशन ऑपरेशन के दौरान क्वेरी करें. इससे कोड की लाइनें सेव होती हैं और सर्वर पर राउंड ट्रिप की संख्या कम होती है.

बदलाव लागू करने के लिए, जनरेट किए गए फ़ील्ड का इस्तेमाल करना

आपके Data Connect ऑपरेशन, आपके स्कीमा में मौजूद टाइप और टाइप के रिलेशनशिप के आधार पर, अपने-आप जनरेट हुए Data Connect फ़ील्ड के सेट को बड़ा करेंगे. जब भी आपके स्कीमा में बदलाव किया जाता है, तो ये फ़ील्ड स्थानीय टूल से जनरेट होते हैं.

जनरेट किए गए फ़ील्ड का इस्तेमाल, बदलाव लागू करने के लिए किया जा सकता है. जैसे, एक टेबल में अलग-अलग रिकॉर्ड बनाना, अपडेट करना, और मिटाना. साथ ही, कई टेबल में ज़्यादा जटिल अपडेट करना.

मान लें कि आपके स्कीमा में Movie टाइप और उससे जुड़ा Actor टाइप है. Data Connect, movie_insert, movie_update, movie_delete फ़ील्ड वगैरह जनरेट करता है.


movie_insert फ़ील्ड के साथ म्यूटेशन

movie_insert फ़ील्ड, Movie टेबल में एक रिकॉर्ड बनाने के लिए, बदलाव दिखाता है.

एक फ़िल्म बनाने के लिए, इस फ़ील्ड का इस्तेमाल करें.

mutation CreateMovie($data: Movie_Data!) {
  movie_insert(data: $data) { key }
}


movie_update फ़ील्ड के साथ म्यूटेशन

movie_update फ़ील्ड, Movie टेबल में किसी एक रिकॉर्ड को अपडेट करने के लिए, बदलाव को दिखाता है.

इस फ़ील्ड का इस्तेमाल करके, किसी एक मूवी को उसकी कुंजी के हिसाब से अपडेट करें.

mutation UpdateMovie($myKey: Movie_Key!, $data: Movie_Data!) {
  movie_update(key: $myKey, data: $data) { key }
}


movie_delete फ़ील्ड के साथ म्यूटेशन

movie_delete फ़ील्ड, Movie टेबल में किसी एक रिकॉर्ड को मिटाने के लिए, बने बदलाव को दिखाता है.

किसी मूवी की कुंजी से उसे मिटाने के लिए, इस फ़ील्ड का इस्तेमाल करें.

  mutation DeleteMovie($myKey: Movie_Key!) {
    movie_delete(key: $myKey) { key }
  }

म्यूटेशन के ज़रूरी एलिमेंट

डेटा कनेक्ट म्यूटेशन, Data Connect एक्सटेंशन वाले GraphQL म्यूटेशन होते हैं. सामान्य GraphQL म्यूटेशन की तरह ही, आपके पास ऑपरेशन का नाम और GraphQL वैरिएबल की सूची तय करने का विकल्प होता है.

Data Connect, @auth और @transaction जैसे पसंद के मुताबिक बनाए गए डायरेक्टिव की मदद से, GraphQL क्वेरी को बढ़ाता है.

इसलिए, इस म्यूटेशन में:

  • mutation टाइप की परिभाषा
  • SignUp ऑपरेशन (बदलाव) का नाम
  • एक वैरिएबल $username ऑपरेशन आर्ग्युमेंट
  • एक डायरेक्टिव, @auth
  • एक फ़ील्ड user_insert.
mutation SignUp($username: String!) @auth(level: USER) {
  user_insert(data: {
    id_expr: "auth.uid"
    username: $username
  })
}

हर म्यूटेशन आर्ग्युमेंट के लिए, टाइप का एलान करना ज़रूरी है. यह String जैसा कोई बिल्ट-इन टाइप हो सकता है या Movie जैसा कस्टम, स्कीमा से तय किया गया टाइप हो सकता है.

बुनियादी म्यूटेशन लिखना

अपने डेटाबेस में अलग-अलग रिकॉर्ड बनाने, अपडेट करने, और मिटाने के लिए, म्यूटेशन लिखना शुरू किया जा सकता है.

बनाएं

आइए, बुनियादी क्रिएशन करते हैं.

# Create a movie based on user input
mutation CreateMovie($title: String!, $releaseYear: Int!, $genre: String!, $rating: Int!) {
  movie_insert(data: {
    title: $title
    releaseYear: $releaseYear
    genre: $genre
    rating: $rating
  })
}

# Create a movie with default values
mutation CreateMovie2 {
  movie_insert(data: {
    title: "Sherlock Holmes"
    releaseYear: 2009
    genre: "Mystery"
    rating: 5
  })
}

या अप्सर्ट.

# Movie upsert using combination of variables and literals
mutation UpsertMovie($title: String!) {
  movie_upsert(data: {
    title: $title
    releaseYear: 2009
    genre: "Mystery"
    rating: 5
    genre: "Mystery/Thriller"
  })
}

अपडेट करना

यहां अपडेट दिए गए हैं. प्रोड्यूसर और डायरेक्टर्स को उम्मीद होती है कि औसत रेटिंग अच्छी हो.

movie_update फ़ील्ड में, रिकॉर्ड की पहचान करने के लिए id आर्ग्युमेंट और data फ़ील्ड होता है. इस फ़ील्ड का इस्तेमाल, अपडेट में वैल्यू सेट करने के लिए किया जा सकता है.

mutation UpdateMovie(
  $id: UUID!,
  $genre: String!,
  $rating: Int!,
  $description: String!
) {
  movie_update(id: $id,
    data: {
      genre: $genre
      rating: $rating
      description: $description
    })
}

एक से ज़्यादा अपडेट करने के लिए, movie_updateMany फ़ील्ड का इस्तेमाल करें.

# Multiple updates (increase all ratings of a genre)
mutation IncreaseRatingForGenre($genre: String!, $rating: Int!) {
  movie_updateMany(
    where: { genre: { eq: $genre } },
    data:
      {
        rating: $rating
      })
}

_update के साथ, वैल्यू बढ़ाने, घटाने, जोड़ने, और पहले जोड़ने की कार्रवाइयों का इस्तेमाल करना

_update और _updateMany म्यूटेशन में, data: में साफ़ तौर पर वैल्यू सेट की जा सकती हैं. हालांकि, वैल्यू अपडेट करने के लिए, अक्सर इंक्रीमेंट जैसे ऑपरेटर को लागू करना ज़्यादा सही होता है.

अपडेट करने के पिछले उदाहरण में बदलाव करने के लिए, मान लें कि आपको किसी खास फ़िल्म की रेटिंग बढ़ानी है. inc ऑपरेटर के साथ rating_update सिंटैक्स का इस्तेमाल किया जा सकता है.

mutation UpdateMovie(
  $id: UUID!,
  $ratingIncrement: Int!
) {
  movie_update(id: $id, data: {
    rating_update: {
      inc: $ratingIncrement
    }
  })
}

Data Connect में फ़ील्ड अपडेट के लिए, ये ऑपरेटर काम करते हैं:

  • inc, Int, Int64, Float, Date, और Timestamp डेटा टाइप को बढ़ाने के लिए
  • dec, Int, Int64, Float, Date, और Timestamp डेटा टाइप को कम करने के लिए

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

  • add, अगर आइटम पहले से ही सूची के टाइप में मौजूद नहीं हैं, तो उन्हें जोड़ने के लिए. हालांकि, वेक्टर सूचियों को शामिल नहीं किया जाता
  • remove, वेक्टर सूचियों को छोड़कर, सूची के टाइप से सभी आइटम हटाने के लिए
  • append, वेक्टर सूचियों को छोड़कर, सूची के टाइप में आइटम जोड़ने के लिए
  • prepend, वेक्टर सूचियों को छोड़कर, सूची के टाइप में आइटम जोड़ने के लिए

मिटाना

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

# Delete by key
mutation DeleteMovie($id: UUID!) {
  movie_delete(id: $id)
}

यहां _deleteMany का इस्तेमाल किया जा सकता है.

# Multiple deletes
mutation DeleteUnpopularMovies($minRating: Int!) {
  movie_deleteMany(where: { rating: { le: $minRating } })
}

रिलेशन पर म्यूटेशन लिखना

किसी संबंध पर, इंप्लिसिट _upsert म्यूटेशन का इस्तेमाल करने का तरीका जानें.

# Create or update a one to one relation
mutation MovieMetadataUpsert($movieId: UUID!, $director: String!) {
  movieMetadata_upsert(
    data: { movie: { id: $movieId }, director: $director }
  )
}

असरदार म्यूटेशन के लिए स्कीमा डिज़ाइन करना

Data Connect में दो अहम सुविधाएं होती हैं. इनकी मदद से, ज़्यादा असरदार म्यूटेशन लिखे जा सकते हैं और राउंड-ट्रिप ऑपरेशन से बचा जा सकता है.

मुख्य स्केलर, छोटे ऑब्जेक्ट आइडेंटिफ़ायर होते हैं. ये आपके स्कीमा के मुख्य फ़ील्ड से Data Connect अपने-आप इकट्ठा होते हैं. मुख्य स्केलर, बेहतर परफ़ॉर्मेंस के लिए होते हैं. इनकी मदद से, एक ही कॉल में अपने डेटा की पहचान और स्ट्रक्चर के बारे में जानकारी मिलती है. ये खास तौर पर तब काम के होते हैं, जब आपको नए रिकॉर्ड पर क्रम से कार्रवाइयां करनी हों और आने वाले ऑपरेशन में पास करने के लिए यूनीक आइडेंटिफ़ायर की ज़रूरत हो. साथ ही, ये तब भी काम के होते हैं, जब आपको ज़्यादा जटिल ऑपरेशन करने के लिए रिलेशनल कुंजियों को ऐक्सेस करना हो.

सर्वर वैल्यू का इस्तेमाल करके, सर्वर को अपनी टेबल में फ़ील्ड को डाइनैमिक तौर पर भरने की अनुमति दी जा सकती है. इसके लिए, expr आर्ग्युमेंट में मौजूद सर्वर-साइड सीईएल एक्सप्रेशन के हिसाब से, सेव की गई या आसानी से कैलकुलेट की जा सकने वाली वैल्यू का इस्तेमाल किया जाता है. उदाहरण के लिए, किसी फ़ील्ड को ऐक्सेस करने पर लागू होने वाले टाइमस्टैंप के साथ फ़ील्ड तय किया जा सकता है. इसके लिए, ऑपरेशन अनुरोध, updatedAt: Timestamp! @default(expr: "request.time") में सेव किए गए समय का इस्तेमाल किया जाता है.

बेहतर म्यूटेशन लिखना: Data Connect को field_expr सिंटैक्स का इस्तेमाल करके वैल्यू दें

मुख्य स्केलर और सर्वर वैल्यू में बताए गए तरीके के मुताबिक, अपने स्कीमा को इस तरह डिज़ाइन किया जा सकता है कि क्लाइंट के अनुरोधों के जवाब में, सर्वर id और तारीखों जैसे सामान्य फ़ील्ड की वैल्यू अपने-आप भर दे.

इसके अलावा, क्लाइंट ऐप्लिकेशन से भेजे गए Data Connect request ऑब्जेक्ट में भेजे गए यूज़र आईडी जैसे डेटा का इस्तेमाल किया जा सकता है.

म्यूटेशन लागू करते समय, field_expr सिंटैक्स का इस्तेमाल करके, सर्वर से जनरेट किए गए अपडेट को ट्रिगर करें या अनुरोधों से डेटा ऐक्सेस करें. उदाहरण के लिए, किसी अनुरोध में सेव की गई अनुमति uid को _upsert ऑपरेशन में पास करने के लिए, userId_expr फ़ील्ड में "auth.uid" पास करें.

# Add a movie to the user's favorites list
mutation AddFavoritedMovie($movieId: UUID!) @auth(level: USER) {
  favorite_movie_upsert(data: { userId_expr: "auth.uid", movieId: $movieId })
}

# Remove a movie from the user's favorites list
mutation DeleteFavoritedMovie($movieId: UUID!) @auth(level: USER) {
  favorite_movie_delete(key: { userId_expr: "auth.uid", movieId: $movieId })
}

इसके अलावा, किसी काम की सूची बनाने वाले ऐप्लिकेशन में नई सूची बनाते समय, id_expr को पास किया जा सकता है. इससे, सूची के लिए यूयूआईडी अपने-आप जनरेट होने का निर्देश, सर्वर को दिया जा सकता है.

mutation CreateTodoListWithFirstItem(
  $listName: String!
) @transaction {
  # Step 1
  todoList_insert(data: {
    id_expr: "uuidV4()", # <-- auto-generated. Or a column-level @default on `type TodoList` will also work
    name: $listName,
  })
}

ज़्यादा जानकारी के लिए, स्केलर रेफ़रंस में _Expr स्केलर देखें.

बेहतर म्यूटेशन लिखना: कई चरणों में होने वाली कार्रवाइयां

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

Data Connect की मदद से, म्यूटेशन में कई चरणों वाला लॉजिक लागू किया जा सकता है. इसके लिए, ये काम किए जा सकते हैं:

  • एक से ज़्यादा 'लिखें' फ़ील्ड

  • आपके म्यूटेशन में कई रीड फ़ील्ड (query फ़ील्ड कीवर्ड का इस्तेमाल करके).

  • @transaction डायरेक्टिव, जो रिलेशनल डेटाबेस से मिलती-जुलती ट्रांज़ैक्शन की सुविधा देता है.

  • @check डायरेक्टिव, जिसकी मदद से, सीईएल एक्सप्रेशन का इस्तेमाल करके, पढ़े गए कॉन्टेंट का आकलन किया जा सकता है. साथ ही, इस आकलन के नतीजों के आधार पर:

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

  • CEL response बाइंडिंग, जो कई चरणों वाले जटिल ऑपरेशन में की गई सभी वैरिएशन और क्वेरी के इकट्ठा किए गए नतीजों को सेव करती है. response बाइंडिंग को ऐक्सेस करने के लिए:

    • @check डायरेक्टिव में, expr: आर्ग्युमेंट के ज़रिए
    • सर्वर वैल्यू के साथ, field_expr सिंटैक्स का इस्तेमाल करना

@transaction डायरेक्टिव

एक से ज़्यादा चरणों में डेटा में बदलाव करने की सुविधा में, लेन-देन का इस्तेमाल करके गड़बड़ी को मैनेज करने की सुविधा भी शामिल है.

@transaction डायरेक्टिव यह लागू करता है कि डेटाबेस ट्रांज़ैक्शन में हमेशा कोई एक बदलाव (उदाहरण के लिए, _insert या _update) या एक से ज़्यादा बदलाव वाले फ़ील्ड का इस्तेमाल किया जाए.

  • @transaction के बिना म्यूटेशन, हर रूट फ़ील्ड को क्रम में एक के बाद एक लागू करते हैं. ऑपरेशन में, किसी भी गड़बड़ी को फ़ील्ड की गड़बड़ी के तौर पर दिखाया जाता है. हालांकि, बाद में होने वाली गड़बड़ियों का असर नहीं दिखाया जाता.

  • @transaction वाले म्यूटेशन, पूरी तरह से कामयाब या पूरी तरह से विफल होते हैं. अगर लेन-देन के किसी फ़ील्ड में कोई गड़बड़ी होती है, तो पूरा लेन-देन रद्द कर दिया जाता है.

@check और @redact डायरेक्टिव

@check डायरेक्टिव यह पुष्टि करता है कि क्वेरी के नतीजों में, तय किए गए फ़ील्ड मौजूद हैं. फ़ील्ड वैल्यू की जांच करने के लिए, कॉमन एक्सप्रेशन लैंग्वेज (सीईएल) एक्सप्रेशन का इस्तेमाल किया जाता है. डायरेक्टिव का डिफ़ॉल्ट व्यवहार, उन नोड की जांच करना और उन्हें अस्वीकार करना है जिनकी वैल्यू null या [] (खाली सूचियां) है.

@redact डायरेक्टिव, क्लाइंट के रिस्पॉन्स के किसी हिस्से को छिपाता है. हटाए गए फ़ील्ड का आकलन अब भी साइड इफ़ेक्ट के लिए किया जाता है. इनमें डेटा में हुए बदलाव और @check भी शामिल हैं. साथ ही, सीईएल एक्सप्रेशन के अगले चरणों में भी ये नतीजे उपलब्ध रहते हैं.

@check, @check(message:), और @redact का इस्तेमाल करें

@check और @redact का मुख्य इस्तेमाल, मिलते-जुलते डेटा को खोजने के लिए किया जाता है. इससे यह तय किया जाता है कि कुछ खास कार्रवाइयों को अनुमति दी जानी चाहिए या नहीं. इसके लिए, लॉजिक में लुकअप का इस्तेमाल किया जाता है, लेकिन इसे क्लाइंट से छिपाया जाता है. आपकी क्वेरी से, क्लाइंट कोड में सही तरीके से मैनेज करने के लिए काम के मैसेज मिल सकते हैं.

उदाहरण के लिए, नीचे दिया गया क्वेरी फ़ील्ड यह जांचता है कि अनुरोध करने वाले के पास, "एडमिन" की सही भूमिका है या नहीं, ताकि वह उन उपयोगकर्ताओं को देख सके जो किसी मूवी में बदलाव कर सकते हैं.

query GetMovieEditors($movieId: UUID!) @auth(level: USER) {
  moviePermission(key: { movieId: $movieId, userId_expr: "auth.uid" }) @redact {
    role @check(expr: "this == 'admin'", message: "You must be an admin to view all editors of a movie.")
  }
  moviePermissions(where: { movieId: { eq: $movieId }, role: { eq: "editor" } }) {
    user {
      id
      username
    }
  }
}

अनुमति की जांच में @check और @redact निर्देशों के बारे में ज़्यादा जानने के लिए, अनुमति के डेटा लुकअप की चर्चा देखें.

कुंजियों की पुष्टि करने के लिए, @check का इस्तेमाल करना

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

इस नतीजे से बचने के लिए, जांचें कि @check डायरेक्टिव का इस्तेमाल करके, कुंजियां मिल सकती हैं या नहीं.

# Delete by key, error if not found
mutation MustDeleteMovie($id: UUID!) @transaction {
  movie_delete(id: $id) @check(expr: "this != null", message: "Movie not found, therefore nothing is deleted")
}

एक से ज़्यादा चरणों में होने वाले म्यूटेशन को चेन करने के लिए, response बाइंडिंग का इस्तेमाल करना

मिलते-जुलते रिकॉर्ड बनाने का बुनियादी तरीका यह है: उदाहरण के लिए, नया Movie और उससे जुड़ी MovieMetadata एंट्री.

  1. Movie के लिए _insert म्यूटेशन को कॉल करना
  2. बनाई गई मूवी की मिली कुंजी को सेव करना
  3. इसके बाद, MovieMetadata रिकॉर्ड बनाने के लिए, दूसरे _insert म्यूटेशन को कॉल करें.

हालांकि, Data Connect की मदद से, इस सामान्य मामले को एक ही प्रोसेस में कई चरणों में हल किया जा सकता है. इसके लिए, दूसरे _insert में पहले _insert के नतीजे ऐक्सेस करें.

मूवी की समीक्षा करने वाला एक अच्छा ऐप्लिकेशन बनाने के लिए, काफ़ी मेहनत करनी पड़ती है. आइए, एक नए उदाहरण की मदद से अपनी 'क्या-क्या करें' सूची को ट्रैक करते हैं.

सर्वर वैल्यू वाले फ़ील्ड सेट करने के लिए, response का इस्तेमाल करना

'क्या-क्या करें' सूची में किए गए इस बदलाव में:

  • response बाइंडिंग, अब तक के आंशिक रिस्पॉन्स ऑब्जेक्ट को दिखाती है. इसमें मौजूद टॉप-लेवल म्यूटेशन फ़ील्ड, मौजूदा फ़ील्ड से पहले के होते हैं.
  • शुरुआती todoList_insert ऑपरेशन के नतीजों को response.todoList_insert.id में बाद में ऐक्सेस किया जाता है. इससे, id (की) फ़ील्ड को तुरंत डाला जा सकता है.
mutation CreateTodoListWithFirstItem(
  $listName: String!,
  $itemContent: String!
) @transaction {
  # Sub-step 1:
  todoList_insert(data: {
    id_expr: "uuidV4()", # <-- auto-generated. Or a column-level @default on `type TodoList` will also work
    name: $listName,
  })
  # Sub-step 2:
  todo_insert(data: {
    listId_expr: "response.todoList_insert.id" # <-- Grab the newly generated ID from the partial response so far.
    content: $itemContent,
  })
}

@check का इस्तेमाल करके फ़ील्ड की पुष्टि करने के लिए, response का इस्तेमाल करें

response, @check(expr: "...") में भी उपलब्ध है. इसलिए, इसका इस्तेमाल करके, ज़्यादा जटिल सर्वर-साइड लॉजिक बनाया जा सकता है. query { … } स्टीप में म्यूटेशन के साथ, क्लाइंट-सर्वर के अतिरिक्त राउंड ट्रिप के बिना बहुत कुछ हासिल किया जा सकता है.

नीचे दिए गए उदाहरण में, ध्यान दें: @check के पास पहले से ही response.query का ऐक्सेस है, क्योंकि @check हमेशा उस चरण के बाद चलता है जिससे वह जुड़ा होता है.

mutation CreateTodoInNamedList(
  $listName: String!,
  $itemContent: String!
) @transaction {
  # Sub-step 1: Look up List.id by its name
  query
  @check(expr: "response.query.todoLists.size() > 0", message: "No such TodoList with the name!")
  @check(expr: "response.query.todoLists.size() < 2", message: "Ambiguous listName!") {
    todoLists(where: { name: $listName }) {
      id
    }
  }
  # Sub-step 2:
  todo_insert(data: {
    listId_expr: "response.todoLists[0].id" # <-- Now we have the parent list ID to insert to
    content: $itemContent,
  })
}

response बाइंडिंग के बारे में ज़्यादा जानकारी के लिए, सीईएल रेफ़रंस देखें.

@transaction और query @check की मदद से, रुके हुए ऑपरेशन को समझना

एक से ज़्यादा चरणों में होने वाले म्यूटेशन में गड़बड़ियां हो सकती हैं:

  • डेटाबेस के ऑपरेशन काम न कर सकते.
  • क्वेरी @check लॉजिक की वजह से, ऑपरेशन बंद हो सकते हैं.

Data Connect का सुझाव है कि आप कई चरणों वाले म्यूटेशन के साथ @transaction डायरेक्टिव का इस्तेमाल करें. इससे, क्लाइंट कोड में आसानी से मैनेज किए जा सकने वाले, ज़्यादा एक जैसे डेटाबेस और बदलाव के नतीजे मिलते हैं:

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

कुछ मामलों में, @transaction का इस्तेमाल न करने का विकल्प चुना जा सकता है: उदाहरण के लिए, अगर आपको ज़्यादा थ्रूपुट, स्केलेबिलिटी या उपलब्धता की ज़रूरत है, तो आपके पास आखिर में एक जैसा डेटा रखने का विकल्प होता है. हालांकि, नतीजे पाने के लिए, आपको अपने डेटाबेस और क्लाइंट कोड को मैनेज करना होगा:

  • अगर डेटाबेस ऑपरेशन की वजह से कोई फ़ील्ड काम नहीं करता है, तो बाकी फ़ील्ड काम करते रहेंगे. हालांकि, काम न करने वाले @check, पूरे ऑपरेशन को खत्म कर देते हैं.
  • रोलबैक नहीं किए जाते. इसका मतलब है कि डेटाबेस की स्थिति अलग-अलग है. इसमें कुछ अपडेट किए गए हैं और कुछ अपडेट नहीं किए जा सके.
  • अगर आपके @check लॉजिक में, पिछले चरण में पढ़े गए और/या लिखे गए डेटा के नतीजों का इस्तेमाल किया जाता है, तो @check के साथ किए जाने वाले आपके ऑपरेशन से, अलग-अलग नतीजे मिल सकते हैं.
  • क्लाइंट कोड में दिखाए गए नतीजे में, सफलता और गड़बड़ी के जवाबों का एक ज़्यादा जटिल मिश्रण होगा.

Data Connect म्यूटेशन के लिए डायरेक्टिव

टाइप और टेबल तय करने के लिए इस्तेमाल किए जाने वाले डायरेक्टिव के अलावा, Data Connect में @auth, @check, @redact, और @transaction डायरेक्टिव भी होते हैं. इनका इस्तेमाल, ऑपरेशन के व्यवहार को बेहतर बनाने के लिए किया जाता है.

निर्देश इन पर लागू होता है ब्यौरा
@auth क्वेरी और म्यूटेशन किसी क्वेरी या म्यूटेशन के लिए अनुमति की नीति तय करता है. अनुमति और पुष्टि करने की गाइड देखें.
@check query कई चरणों वाले ऑपरेशन में फ़ील्ड यह पुष्टि करता है कि क्वेरी के नतीजों में बताए गए फ़ील्ड मौजूद हैं. फ़ील्ड वैल्यू की जांच करने के लिए, कॉमन एक्सप्रेशन लैंग्वेज (सीईएल) एक्सप्रेशन का इस्तेमाल किया जाता है. एक से ज़्यादा चरणों में होने वाले ऑपरेशन देखें.
@redact क्वेरी क्लाइंट के जवाब के किसी हिस्से को छिपाता है. एक से ज़्यादा चरणों वाले ऑपरेशन देखें.
@transaction म्यूटेशन यह पक्का करता है कि कोई म्यूटेशन हमेशा डेटाबेस ट्रांज़ैक्शन में चलता है. एक से ज़्यादा चरणों में होने वाले ऑपरेशन देखें.

अगले चरण

आपकी दिलचस्पी इनमें हो सकती है: