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
และ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 มีฟีเจอร์สำคัญ 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 ช่วยให้คุณใช้ตรรกะแบบหลายขั้นตอนในการเปลี่ยนแปลงได้โดย รองรับสิ่งต่อไปนี้
ฟิลด์การเขียนหลายรายการ
ฟิลด์การอ่านหลายรายการในการเปลี่ยนแปลง (ใช้คีย์เวิร์ด
query
field)คำสั่ง
@transaction
ซึ่งให้การรองรับธุรกรรมที่คุ้นเคยจากฐานข้อมูลเชิงสัมพันธ์@check
คำสั่งที่ช่วยให้คุณประเมินเนื้อหาของการอ่านโดยใช้นิพจน์ 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
- จัดเก็บคีย์ที่ส่งคืนของภาพยนตร์ที่สร้างขึ้น
- จากนั้นเรียกใช้
_insert
mutation ที่ 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
- การให้สิทธิ์การเปลี่ยนแปลงตามคู่มือการให้สิทธิ์
- การเรียกใช้การเปลี่ยนแปลงจากโค้ดฝั่งไคลเอ็นต์สำหรับ เว็บ iOS, Android และ Flutter
- การดำเนินการกับข้อมูลแบบเป็นกลุ่มด้วยการเปลี่ยนแปลง