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
फ़ील्ड के साथ म्यूटेशन
|
एक फ़िल्म बनाने के लिए, इस फ़ील्ड का इस्तेमाल करें. mutation CreateMovie($data: Movie_Data!) { movie_insert(data: $data) { key } } |
movie_update
फ़ील्ड के साथ म्यूटेशन
|
इस फ़ील्ड का इस्तेमाल, किसी एक फ़िल्म को उसकी कुंजी के हिसाब से अपडेट करने के लिए करें. mutation UpdateMovie($myKey: Movie_Key!, $data: Movie_Data!) { movie_update(key: $myKey, data: $data) { key } } |
movie_delete
फ़ील्ड के साथ म्यूटेशन
|
इस फ़ील्ड का इस्तेमाल करके, किसी एक फ़िल्म को उसकी कुंजी के हिसाब से मिटाया जा सकता है. 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
एंट्री बनाने के लिए:
Movie
के लिए_insert
म्यूटेशन को कॉल करना- बनाई गई मूवी की वापस की गई कुंजी को सेव करता है
- इसके बाद,
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 |
म्यूटेशन | यह लागू करता है कि म्यूटेशन हमेशा डेटाबेस लेन-देन में चले. एक से ज़्यादा चरणों वाली कार्रवाइयां देखें. |
अगले चरण
आपकी इनमें दिलचस्पी हो सकती है:
- एआई की मदद से काम करने वाले टूल का इस्तेमाल करके, अपने ऐप्लिकेशन के लिए म्यूटेशन जनरेट करना
- अनुमति से जुड़ी गाइड के मुताबिक, म्यूटेशन की अनुमति देना
- वेब, iOS, Android, और Flutter के लिए, क्लाइंट कोड से म्यूटेशन कॉल करना.
- म्यूटेशन की मदद से, डेटा से जुड़ी कई कार्रवाइयां एक साथ करना