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

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

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

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

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

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

Data Connect म्यूटेशन की विशेषताएं

Data Connect की मदद से, PostgreSQL डेटाबेस में बुनियादी बदलाव किए जा सकते हैं. इसके लिए, ये तरीके अपनाए जा सकते हैं:

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

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

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

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

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, GraphQL क्वेरी को पसंद के मुताबिक बनाए गए निर्देशों के साथ बढ़ाता है. जैसे, @auth और @transaction.

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

  • 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, फ़ील्ड अपडेट करने के लिए इन ऑपरेटर का इस्तेमाल करता है:

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

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

  • 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 आपके स्कीमा में मौजूद मुख्य फ़ील्ड से अपने-आप इकट्ठा होते हैं. मुख्य स्केलर, परफ़ॉर्मेंस से जुड़े होते हैं. इनकी मदद से, एक ही कॉल में अपने डेटा की पहचान और स्ट्रक्चर के बारे में जानकारी पाई जा सकती है. ये खास तौर पर तब काम आते हैं, जब आपको नए रिकॉर्ड पर क्रम से कार्रवाइयां करनी हों और आने वाले समय में होने वाले ऑपरेशनों के लिए, आपको यूनीक आइडेंटिफ़ायर की ज़रूरत हो. साथ ही, इनका इस्तेमाल तब भी किया जा सकता है, जब आपको ज़्यादा जटिल कार्रवाइयां करने के लिए, रिलेशनल कुंजियों को ऐक्सेस करना हो.

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

ऐडवांस म्यूटेशन लिखना: Data Connect को field_expr सिंटैक्स का इस्तेमाल करके वैल्यू सप्लाई करने की अनुमति देना

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

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

म्यूटेशन लागू करते समय, field_expr सिंटैक्स का इस्तेमाल करके, सर्वर से जनरेट हुए अपडेट ट्रिगर करें या अनुरोधों से डेटा ऐक्सेस करें. उदाहरण के लिए, किसी _upsert ऑपरेशन के अनुरोध में सेव की गई अनुमति uid को पास करने के लिए, 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 डायरेक्टिव, जिसकी मदद से CEL एक्सप्रेशन का इस्तेमाल करके, रीड के कॉन्टेंट का आकलन किया जा सकता है. साथ ही, इस आकलन के नतीजों के आधार पर:

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

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

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

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

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

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

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

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

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

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

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

@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,
  })
}

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

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 बाइंडिंग के बारे में ज़्यादा जानकारी के लिए, CEL रेफ़रंस देखें.

@transaction और query @check की मदद से, रोकी गई कार्रवाइयों को समझना

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

  • डेटाबेस से जुड़ी कार्रवाइयां पूरी नहीं हो सकती हैं.
  • क्वेरी @check लॉजिक, कार्रवाइयों को बंद कर सकता है.

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

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

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

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

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

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

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

अगले चरण

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