Firebase SQL Connect की मदद से, PostgreSQL के उन इंस्टेंस के लिए कनेक्टर बनाए जा सकते हैं जिन्हें Cloud SQL से मैनेज किया जाता है. ये कनेक्टर, क्वेरी और म्यूटेशन के कॉम्बिनेशन होते हैं. इनकी मदद से, स्कीमा से डेटा का इस्तेमाल किया जा सकता है.
उस गाइड में, डिप्लॉय किए जा सकने वाले और ऐडहॉक एडमिन कार्रवाइयों, दोनों के बारे में बताया गया है. इनमें म्यूटेशन भी शामिल हैं.
- डिप्लॉय किए जा सकने वाले म्यूटेशन वे होते हैं जिन्हें क्लाइंट ऐप्लिकेशन से कॉल करने के लिए, कनेक्टर में लागू किया जाता है. इसके लिए, एपीआई एंडपॉइंट तय किए जाते हैं. SQL Connect इन म्यूटेशन में पुष्टि करने और अनुमति देने की सुविधा को इंटिग्रेट करता है. साथ ही, आपके एपीआई के आधार पर क्लाइंट एसडीके जनरेट करता है.
- ऐडहॉक एडमिन म्यूटेशन को, टेबल में डेटा भरने और उन्हें मैनेज करने के लिए, खास अधिकारों वाले एनवायरमेंट से चलाया जाता है. इन्हें Firebase console में, Firebase Admin SDK का इस्तेमाल करके खास अधिकारों वाले एनवायरमेंट से, और SQL Connect VS Code एक्सटेंशन का इस्तेमाल करके लोकल डेवलपमेंट एनवायरमेंट में बनाया और लागू किया जा सकता है.
इस गाइड में, डिप्लॉय किए जा सकने वाले म्यूटेशन के बारे में ज़्यादा जानकारी दी गई है.
SQL Connect म्यूटेशन की सुविधाएं
SQL Connect की मदद से, PostgreSQL डेटाबेस में बुनियादी म्यूटेशन किए जा सकते हैं. इसके लिए, इन तरीकों का इस्तेमाल किया जा सकता है:
- सीआरयूडी कार्रवाइयां करना
- लेन-देन की मदद से, कई चरणों वाली कार्रवाइयों को मैनेज करना
हालांकि, GraphQL के लिए SQL Connect's के एक्सटेंशन की मदद से, बेहतर म्यूटेशन लागू किए जा सकते हैं. इससे ऐप्लिकेशन ज़्यादा तेज़ी से और बेहतर तरीके से काम करते हैं:
- रिकॉर्ड पर बार-बार की जाने वाली कार्रवाइयों को आसान बनाने के लिए, कई कार्रवाइयों से मिलने वाले की स्केलर का इस्तेमाल करना
- सर्वर की ओर से दी जाने वाली कार्रवाइयों से डेटा भरने के लिए, सर्वर वैल्यू का इस्तेमाल करना
- डेटा देखने के लिए, कई चरणों वाली म्यूटेशन कार्रवाइयों के दौरान क्वेरी करना. इससे कोड की लाइनें और सर्वर पर राउंड ट्रिप सेव होती हैं.
म्यूटेशन लागू करने के लिए, जनरेट किए गए फ़ील्ड का इस्तेमाल करना
आपकी SQL Connect कार्रवाइयां, SQL Connect की ओर से अपने-आप जनरेट किए गए फ़ील्ड के सेट को बढ़ाएंगी. ये फ़ील्ड, आपके स्कीमा में मौजूद टाइप और टाइप के रिलेशनशिप के आधार पर जनरेट किए जाते हैं. जब भी स्कीमा में बदलाव किया जाता है, तो ये फ़ील्ड लोकल टूलिंग से जनरेट होते हैं.
जनरेट किए गए फ़ील्ड का इस्तेमाल, म्यूटेशन लागू करने के लिए किया जा सकता है. इसके लिए, सिंगल टेबल में अलग-अलग रिकॉर्ड बनाने, अपडेट करने, और मिटाने से लेकर, कई टेबल को अपडेट करने जैसी ज़्यादा जटिल कार्रवाइयां की जा सकती हैं.मान लें कि आपके स्कीमा में Movie टाइप और उससे जुड़ा Actor टाइप शामिल है.
SQL Connect जनरेट करता है movie_insert,
movie_update, movie_delete फ़ील्ड वगैरह.
movie_insert फ़ील्ड के साथ म्यूटेशन
|
The |
इस फ़ील्ड का इस्तेमाल करके, एक मूवी बनाई जा सकती है. mutation CreateMovie($title: String!, $releaseYear: Int!, $genre: String!, $rating: Int!) { movie_insert(data: { title: $title releaseYear: $releaseYear genre: $genre rating: $rating }) } |
movie_update फ़ील्ड के साथ म्यूटेशन
|
|
इस फ़ील्ड का इस्तेमाल करके, उसकी कुंजी के हिसाब से एक मूवी अपडेट की जा सकती है. mutation UpdateMovie($myKey: Movie_Key!, $genre: String, $rating: Int, $description: String) { movie_update(key: $myKey, data: { genre: $genre rating: $rating description: $description }) } |
movie_delete फ़ील्ड के साथ म्यूटेशन
|
|
इस फ़ील्ड का इस्तेमाल करके, उसकी कुंजी के हिसाब से एक मूवी मिटाई जा सकती है. mutation DeleteMovie($myKey: Movie_Key!) { movie_delete(key: $myKey) { key } } |
म्यूटेशन के ज़रूरी एलिमेंट
SQL Connect म्यूटेशन, SQL Connect एक्सटेंशन वाले GraphQL म्यूटेशन होते हैं. ठीक उसी तरह जैसे सामान्य GraphQL म्यूटेशन में, यहां भी किसी कार्रवाई का नाम और GraphQL वैरिएबल की सूची तय की जा सकती है.
SQL 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
}
})
}
SQL 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 }
)
}
बेहतर म्यूटेशन के लिए स्कीमा डिज़ाइन करना
SQL Connect में दो अहम सुविधाएं हैं. इनकी मदद से, बेहतर म्यूटेशन लिखे जा सकते हैं और राउंड-ट्रिप कार्रवाइयां सेव की जा सकती हैं.
की स्केलर, ऑब्जेक्ट के छोटे आइडेंटिफ़ायर होते हैं. SQL Connect इन्हें आपके स्कीमा में मौजूद मुख्य फ़ील्ड से अपने-आप इकट्ठा करता है. की स्केलर, बेहतर तरीके से काम करते हैं. इनकी मदद से, एक ही कॉल में अपने डेटा की पहचान और स्ट्रक्चर के बारे में जानकारी पाई जा सकती है. ये खास तौर पर तब काम के होते हैं, जब नए रिकॉर्ड पर क्रम से कार्रवाइयां करनी हों और आने वाली कार्रवाइयों के लिए यूनीक आइडेंटिफ़ायर की ज़रूरत हो. साथ ही, जब ज़्यादा जटिल कार्रवाइयां करने के लिए, रिलेशनल की को ऐक्सेस करना हो.
सर्वर वैल्यू का इस्तेमाल करके, सर्वर को expr आर्ग्युमेंट में दिए गए सर्वर-साइड CEL एक्सप्रेशन के मुताबिक,
सेव की गई या आसानी से कैलकुलेट की जा सकने वाली वैल्यू का इस्तेमाल करके, अपनी टेबल में फ़ील्ड को डाइनैमिक तरीके से भरने की अनुमति दी जा सकती है. उदाहरण के लिए, किसी फ़ील्ड को उस समय के टाइमस्टैंप के साथ तय किया जा सकता है जब फ़ील्ड को ऐक्सेस किया जाता है. इसके लिए, कार्रवाई के अनुरोध में सेव किए गए समय का इस्तेमाल किया जाता है. जैसे, updatedAt: Timestamp!
@default(expr: "request.time").
बेहतर म्यूटेशन लिखना: SQL Connect को field_expr सिंटैक्स का इस्तेमाल करके वैल्यू सप्लाई करने की अनुमति देना
की स्केलर और सर्वर वैल्यू में बताए गए तरीके के मुताबिक,
अपने स्कीमा को इस तरह डिज़ाइन किया जा सकता है कि क्लाइंट के अनुरोधों के जवाब में, सर्वर, id और तारीख जैसे सामान्य
फ़ील्ड के लिए वैल्यू भर दे.
इसके अलावा, क्लाइंट ऐप्लिकेशन से भेजे गए डेटा का इस्तेमाल किया जा सकता है. जैसे, यूज़र आईडी.SQL 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 स्केलर के
रेफ़रंस में स्केलर देखें.
बेहतर म्यूटेशन लिखना: कई चरणों वाली कार्रवाइयां
कई ऐसी स्थितियां हो सकती हैं जिनमें एक म्यूटेशन में, लिखने के लिए एक से ज़्यादा फ़ील्ड (जैसे, इंसर्ट) शामिल करने की ज़रूरत पड़ सकती है. उदाहरण के लिए, इंसर्ट या अपडेट करने से पहले, मौजूदा डेटा को देखने और उसकी पुष्टि करने के लिए, म्यूटेशन लागू करने के दौरान अपने डेटाबेस को पढ़ने की ज़रूरत पड़ सकती है. इन विकल्पों से, दोतरफ़ा यात्रा कार्रवाइयां और इसलिए लागत सेव होती है.
SQL 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 जैसे कुछ म्यूटेशन फ़ील्ड, अगर तय की गई कुंजी वाला कोई रिकॉर्ड मौजूद नहीं है, तो कोई कार्रवाई नहीं कर सकते. इसी तरह, लुकअप में null या खाली सूची दिख सकती है. इन्हें गड़बड़ियां नहीं माना जाता. इसलिए, रोलबैक ट्रिगर नहीं होंगे.
इस नतीजे से बचने के लिए, जांच करें कि @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 एंट्री बनाई जाए:
Movieके लिए_insertम्यूटेशन को कॉल करें- बनाई गई मूवी की कुंजी सेव करें
- इसके बाद,
MovieMetadataरिकॉर्ड बनाने के लिए, दूसरा_insertम्यूटेशन कॉल करें.
हालांकि, SQL 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 बाइंडिंग के बारे में ज़्यादा जानकारी के लिए, CEL का रेफ़रंस देखें.
@transaction और query @check के साथ, बीच में रुकने वाली कार्रवाइयों के बारे में जानकारी
कई चरणों वाले म्यूटेशन में गड़बड़ियां आ सकती हैं:
- डेटाबेस की कार्रवाइयां फ़ेल हो सकती हैं.
- query
@checkलॉजिक, कार्रवाइयों को रोक सकता है.
SQL Connect का सुझाव है कि कई चरणों वाले म्यूटेशन के साथ
, @transaction डायरेक्टिव का इस्तेमाल करें. इससे, डेटाबेस और म्यूटेशन के नतीजे ज़्यादा एक जैसे होते हैं. साथ ही, क्लाइंट कोड में इन्हें मैनेज करना आसान होता है:
- पहली गड़बड़ी या
@checkके फ़ेल होने पर, कार्रवाई रुक जाएगी. इसलिए, बाद के किसी भी फ़ील्ड को लागू करने या CEL के आकलन को मैनेज करने की ज़रूरत नहीं है. - डेटाबेस की गड़बड़ियों या
@checkलॉजिक के जवाब में, रोलबैक किए जाते हैं. इससे, डेटाबेस की स्थिति एक जैसी बनी रहती है. - क्लाइंट कोड को हमेशा रोलबैक की गड़बड़ी दिखाई जाती है.
कुछ ऐसे मामले हो सकते हैं जिनमें @transaction का इस्तेमाल न किया जाए. उदाहरण के लिए, अगर आपको ज़्यादा थ्रूपुट, स्केलेबिलिटी या उपलब्धता की ज़रूरत है, तो हो सकता है कि आप आखिर में कंसिस्टेंसी का विकल्प चुनें. हालांकि, नतीजों के लिए, आपको अपने डेटाबेस और क्लाइंट कोड को मैनेज करना होगा:
- अगर डेटाबेस की कार्रवाइयों की वजह से कोई फ़ील्ड फ़ेल होता है, तो बाद के फ़ील्ड लागू होते रहेंगे. हालांकि,
@checkके फ़ेल होने पर, पूरी कार्रवाई रुक जाती है. - रोलबैक नहीं किए जाते. इसका मतलब है कि डेटाबेस की स्थिति मिली-जुली होती है. इसमें कुछ अपडेट सफल होते हैं और कुछ अपडेट फ़ेल होते हैं.
@checkके साथ आपकी कार्रवाइयों के नतीजे ज़्यादा अलग-अलग हो सकते हैं. ऐसा तब होता है, जब@checkलॉजिक में, पिछले चरण में पढ़ने और/या लिखने के नतीजों का इस्तेमाल किया जाता है.- क्लाइंट कोड को मिलने वाले नतीजे में, सफलता और गड़बड़ी के जवाबों का ज़्यादा जटिल मिक्स शामिल होगा. इसे मैनेज करना होगा.
SQL Connect म्यूटेशन के लिए डायरेक्टिव
टाइप और टेबल तय करने के लिए इस्तेमाल किए जाने वाले डायरेक्टिव के अलावा,
SQL Connect में @auth, @check, @redact और
@transaction डायरेक्टिव भी शामिल हैं. इनका इस्तेमाल, कार्रवाइयों के व्यवहार को बेहतर बनाने के लिए किया जाता है.
| डायरेक्टिव | इन पर लागू होता है | ब्यौरा |
|---|---|---|
@auth |
क्वेरी और म्यूटेशन | किसी क्वेरी या म्यूटेशन के लिए, अनुमति की नीति तय करता है. अनुमति और अटेस्टेशन की गाइड देखें . |
@check |
कई चरणों वाली कार्रवाइयों में query फ़ील्ड |
यह पुष्टि करता है कि क्वेरी के नतीजों में तय किए गए फ़ील्ड मौजूद हैं. फ़ील्ड की वैल्यू की जांच करने के लिए, कॉमन एक्सप्रेशन लैंग्वेज (सीईएल) एक्सप्रेशन का इस्तेमाल किया जाता है. कई चरणों वाली कार्रवाइयां देखें . |
@redact |
क्वेरी | क्लाइंट को मिलने वाले जवाब के किसी हिस्से को हटा देता है. कई चरणों वाली कार्रवाइयां देखें . |
@transaction |
म्यूटेशन | यह पक्का करता है कि म्यूटेशन हमेशा डेटाबेस के लेन-देन में चले. कई चरणों वाली कार्रवाइयां देखें . |
अगले चरण
आपकी इसमें रुचि हो सकती है:
- एआई की मदद करने वाले टूल का इस्तेमाल करके, अपने ऐप्लिकेशन के लिए म्यूटेशन जनरेट करना
- अनुमति की गाइड के मुताबिक, अपने म्यूटेशन को अनुमति देना
- वेब, iOS, Android, और Flutter के लिए, अपने क्लाइंट कोड से म्यूटेशन को कॉल करना.
- म्यूटेशन की मदद से, बल्क में डेटा की कार्रवाइयां करना