Firebase Data Connect ช่วยให้คุณสร้างเครื่องมือเชื่อมต่อสำหรับอินสแตนซ์ PostgreSQL ที่จัดการด้วย Google Cloud SQL ได้ เครื่องมือเชื่อมต่อเหล่านี้เป็นการผสมผสานระหว่าง การค้นหาและการเปลี่ยนแปลงสำหรับการใช้ข้อมูลจากสคีมา
คู่มือการเริ่มต้นใช้งานได้แนะนำสคีมาแอปรีวิวภาพยนตร์สำหรับ PostgreSQL
คู่มือดังกล่าวได้แนะนําการดําเนินการดูแลระบบทั้งแบบที่นําไปใช้ได้และแบบเฉพาะกิจ รวมถึงการเปลี่ยนแปลงด้วย
- การเปลี่ยนแปลงที่ใช้ได้คือการเปลี่ยนแปลงที่คุณใช้เพื่อเรียกจากแอปไคลเอ็นต์ใน ตัวเชื่อมต่อ โดยมีปลายทาง API ที่คุณกำหนด Data Connectผสานรวม การตรวจสอบสิทธิ์และการให้สิทธิ์เข้ากับการเปลี่ยนแปลงเหล่านี้ และสร้าง SDK ของไคลเอ็นต์ ตาม API ของคุณ
- การเปลี่ยนแปลงการดูแลระบบเฉพาะกิจจะทำงานจากสภาพแวดล้อมที่มีสิทธิ์เพื่อ สร้างและจัดการตาราง คุณสร้างและเรียกใช้ได้ใน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 ที่มีData Connect ส่วนขยาย เช่นเดียวกับการเปลี่ยนแปลง 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: แต่ส่วนใหญ่มักจะสมเหตุสมผลกว่าที่จะใช้โอเปอเรเตอร์ เช่น การเพิ่ม เพื่ออัปเดต
ค่า
หากต้องการแก้ไขตัวอย่างการอัปเดตก่อนหน้านี้ ให้สมมติว่าคุณต้องการเพิ่มคะแนน
ของภาพยนตร์เรื่องหนึ่ง คุณใช้ไวยากรณ์ rating_update กับโอเปอเรเตอร์ inc
ได้
mutation UpdateMovie(
$id: UUID!,
$ratingIncrement: Int!
) {
movie_update(id: $id, data: {
rating_update: {
inc: $ratingIncrement
}
})
}
Data Connect รองรับตัวดำเนินการต่อไปนี้สำหรับการอัปเดตฟิลด์
incเพื่อเพิ่มประเภทข้อมูลInt,Int64,Float,DateและTimestampdecเพื่อลดประเภทข้อมูล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 มีฟีเจอร์สำคัญ 2 อย่างที่ช่วยให้คุณ เขียนการเปลี่ยนแปลงที่มีประสิทธิภาพมากขึ้นและประหยัดการดำเนินการแบบไปกลับ
สเกลาร์คีย์คือตัวระบุออบเจ็กต์แบบย่อที่ Data Connect ประกอบขึ้นโดยอัตโนมัติจากฟิลด์คีย์ในสคีมา สเกลาร์หลักเกี่ยวข้องกับประสิทธิภาพ ซึ่งช่วยให้คุณค้นหาข้อมูลเกี่ยวกับตัวตนและโครงสร้างของข้อมูลได้ในการเรียกใช้ครั้งเดียว โดยเฉพาะอย่างยิ่งเมื่อคุณต้องการดำเนินการตามลำดับกับระเบียนใหม่และต้องการตัวระบุที่ไม่ซ้ำกันเพื่อส่งไปยังการดำเนินการที่จะเกิดขึ้น รวมถึงเมื่อคุณต้องการเข้าถึงคีย์เชิงสัมพันธ์เพื่อดำเนินการที่ซับซ้อนเพิ่มเติม
การใช้ค่าเซิร์ฟเวอร์ช่วยให้เซิร์ฟเวอร์สามารถป้อนข้อมูลแบบไดนามิกลงในช่องต่างๆ
ในตารางได้โดยใช้ค่าที่จัดเก็บไว้หรือค่าที่คำนวณได้ตาม
นิพจน์ CEL ฝั่งเซิร์ฟเวอร์ที่เฉพาะเจาะจงในอาร์กิวเมนต์ expr เช่น คุณ
สามารถกำหนดฟิลด์ที่มีการประทับเวลาเมื่อเข้าถึงฟิลด์โดยใช้
เวลาที่จัดเก็บไว้ในคำขอการดำเนินการ updatedAt: Timestamp!
@default(expr: "request.time")
เขียนการเปลี่ยนแปลงขั้นสูง: ให้ Data Connect ระบุค่าโดยใช้ไวยากรณ์ field_expr
ดังที่ได้กล่าวไว้ในสเกลาร์และค่าเซิร์ฟเวอร์หลัก
คุณสามารถออกแบบสคีมาเพื่อให้เซิร์ฟเวอร์ป้อนค่าสำหรับฟิลด์ทั่วไป
เช่น idและวันที่ในการตอบกลับคำขอของไคลเอ็นต์
นอกจากนี้ คุณยังใช้ประโยชน์จากข้อมูล เช่น รหัสผู้ใช้ ที่ส่งในออบเจ็กต์ Data Connect request จากแอปไคลเอ็นต์ได้ด้วย
เมื่อใช้การเปลี่ยนแปลง ให้ใช้ไวยากรณ์ field_expr เพื่อทริกเกอร์การอัปเดตที่เซิร์ฟเวอร์สร้างขึ้นหรือเข้าถึงข้อมูลจากคำขอ เช่น หากต้องการส่งuidการให้สิทธิ์ที่เก็บไว้ในคำขอไปยังการดำเนินการ _upsert ให้ส่ง"auth.uid"ในช่อง userId_expr
# 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 เพื่อสั่งให้เซิร์ฟเวอร์สร้าง UUID สำหรับรายการโดยอัตโนมัติ
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 ช่วยให้คุณใช้ตรรกะแบบหลายขั้นตอนในการเปลี่ยนแปลงได้โดย รองรับสิ่งต่อไปนี้
ฟิลด์การเขียนหลายรายการ
ฟิลด์การอ่านหลายรายการในการเปลี่ยนแปลง (ใช้คีย์เวิร์ด
queryfield)@transactionคำสั่งซึ่งให้การรองรับธุรกรรมที่คุ้นเคยจากฐานข้อมูลเชิงสัมพันธ์@checkDirective ซึ่งช่วยให้คุณประเมินเนื้อหาของการอ่านได้โดยใช้นิพจน์ CEL และอิงตามผลลัพธ์ของการประเมินดังกล่าว- ดำเนินการสร้าง อัปเดต และลบตามที่กำหนดโดยการเปลี่ยนแปลง
- ดำเนินการต่อเพื่อแสดงผลลัพธ์ของฟิลด์การค้นหา
- ใช้ข้อความที่ส่งคืนเพื่อดำเนินการตามตรรกะที่เหมาะสมในโค้ดไคลเอ็นต์
@redactคำสั่งที่ช่วยให้คุณละเว้นผลลัพธ์ของฟิลด์การค้นหาจากผลลัพธ์ของโปรโตคอลแบบมีสายการเชื่อมโยง CEL
responseซึ่งจัดเก็บผลลัพธ์ที่สะสมของการกลายพันธุ์และการค้นหาทั้งหมดที่ดำเนินการในการดำเนินการที่ซับซ้อนแบบหลายขั้นตอน คุณสามารถ เข้าถึงการเชื่อมโยงresponseได้โดยทำดังนี้- ในคำสั่ง
@checkผ่านอาร์กิวเมนต์expr: - ใช้ไวยากรณ์
field_exprกับค่าเซิร์ฟเวอร์
- ในคำสั่ง
คำสั่ง @transaction
การรองรับการเปลี่ยนแปลงแบบหลายขั้นตอนรวมถึงการจัดการข้อผิดพลาดโดยใช้ธุรกรรม
คำสั่ง @transaction บังคับให้การเปลี่ยนแปลงที่มีฟิลด์เขียนเดียว (เช่น _insert หรือ _update) หรือมีฟิลด์เขียนหลายรายการทำงานในการทำธุรกรรมฐานข้อมูลเสมอ
การเปลี่ยนแปลงที่ไม่มี
@transactionจะดำเนินการฟิลด์รูทแต่ละรายการทีละรายการ ตามลำดับ การดำเนินการจะแสดงข้อผิดพลาดเป็นข้อผิดพลาดของฟิลด์บางส่วน แต่จะไม่แสดงผลกระทบของการดำเนินการที่ตามมาการเปลี่ยนแปลงที่มี
@transactionจะรับประกันว่าสำเร็จทั้งหมดหรือล้มเหลวทั้งหมด หากฟิลด์ใดฟิลด์หนึ่งในธุรกรรมล้มเหลว ระบบจะย้อนกลับธุรกรรมทั้งหมด
คำสั่ง @check และ @redact
คำสั่ง @check จะยืนยันว่าฟิลด์ที่ระบุมีอยู่ในผลการค้นหาของคำค้นหา ระบบจะใช้นิพจน์ Common Expression Language (CEL) เพื่อทดสอบค่าฟิลด์
ลักษณะการทำงานเริ่มต้นของคำสั่งคือการตรวจสอบและปฏิเสธ
โหนดที่มีค่าเป็น 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 ที่เชื่อมโยงกัน มีดังนี้
- เรียกใช้การเปลี่ยนแปลง
_insertสำหรับMovie - จัดเก็บคีย์ที่ส่งคืนของภาพยนตร์ที่สร้างขึ้น
- จากนั้นเรียกใช้
_insertmutation ที่ 2 เพื่อสร้างระเบียนMovieMetadata
แต่ด้วย Data Connect คุณสามารถจัดการกรณีทั่วไปนี้ได้ในการดำเนินการแบบหลายขั้นตอนเดียวโดยการเข้าถึงผลลัพธ์ของ _insert แรกใน _insert ที่สอง
การสร้างแอปรีวิวภาพยนตร์ที่ประสบความสำเร็จต้องใช้ความพยายามอย่างมาก มาติดตามสิ่งที่ต้องทำ ด้วยตัวอย่างใหม่กัน
ใช้ response เพื่อตั้งค่าช่องที่มีค่าเซิร์ฟเวอร์
ในการเปลี่ยนแปลงรายการสิ่งที่ต้องทำต่อไปนี้
- การเชื่อมโยง
responseแสดงออบเจ็กต์การตอบกลับบางส่วนจนถึงตอนนี้ ซึ่ง รวมถึงฟิลด์การกลายพันธุ์ระดับบนสุดทั้งหมดก่อนฟิลด์ปัจจุบัน - ผลลัพธ์ของการดำเนินการ
todoList_insertครั้งแรก ซึ่งจะแสดงผลฟิลด์id(คีย์) จะได้รับการเข้าถึงในภายหลังในresponse.todoList_insert.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 ยังมีคําสั่ง @auth, @check, @redact และ @transaction สําหรับเพิ่มลักษณะการทํางานของการดําเนินการ
| คำสั่ง | ใช้ได้กับ | คำอธิบาย |
|---|---|---|
@auth |
การค้นหาและการเปลี่ยนแปลง | กำหนดนโยบายการให้สิทธิ์สำหรับการค้นหาหรือการเปลี่ยนแปลง ดูคู่มือการให้สิทธิ์และการรับรอง |
@check |
query ฟิลด์ในการดำเนินการแบบหลายขั้นตอน |
ยืนยันว่าฟิลด์ที่ระบุมีอยู่ในผลการค้นหา ระบบจะใช้นิพจน์ Common Expression Language (CEL) เพื่อทดสอบค่าฟิลด์ ดู การดำเนินการแบบหลายขั้นตอน |
@redact |
คำค้นหา | ปกปิดบางส่วนของคำตอบจากไคลเอ็นต์ ดู การดำเนินการแบบหลายขั้นตอน |
@transaction |
การกลายพันธุ์ | บังคับให้การเปลี่ยนแปลงทำงานในธุรกรรมฐานข้อมูลเสมอ ดู การดำเนินการแบบหลายขั้นตอน |
ขั้นตอนถัดไป
คุณอาจสนใจ
- สร้างการกลายพันธุ์สำหรับแอปโดยใช้เครื่องมือความช่วยเหลือจาก AI
- การให้สิทธิ์การเปลี่ยนแปลงตามคู่มือการให้สิทธิ์
- การเรียกใช้การเปลี่ยนแปลงจากโค้ดไคลเอ็นต์สำหรับ web, iOS, Android และ Flutter
- การดำเนินการกับข้อมูลแบบเป็นกลุ่มด้วยการเปลี่ยนแปลง