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
फ़ील्ड के साथ म्यूटेशन
|
एक फ़िल्म बनाने के लिए, इस फ़ील्ड का इस्तेमाल करें. 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, @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
एंट्री.
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,
})
}
@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 |
म्यूटेशन | यह पक्का करता है कि कोई म्यूटेशन हमेशा डेटाबेस ट्रांज़ैक्शन में चलता है. एक से ज़्यादा चरणों में होने वाले ऑपरेशन देखें. |
अगले चरण
आपकी दिलचस्पी इनमें हो सकती है:
- एआई की मदद से काम करने वाले टूल का इस्तेमाल करके, अपने ऐप्लिकेशन के लिए म्यूटेशन जनरेट करना
- अनुमति से जुड़ी गाइड के मुताबिक, अपने म्यूटेशन को अनुमति देना
- वेब, iOS, Android और Flutter के लिए, अपने क्लाइंट कोड से म्यूटेशन को कॉल करना.
- बदलावों की मदद से, बल्क डेटा ऑपरेशन करना