วิธีประหยัดอินเทอร์เน็ต |
|
|---|---|
| PUT | เขียนหรือแทนที่ข้อมูลในเส้นทางที่กำหนด เช่น fireblog/users/user1/<data> |
| PATCH | อัปเดตคีย์บางรายการสำหรับเส้นทางที่กำหนดโดยไม่ต้องแทนที่ข้อมูลทั้งหมด |
| POST | เพิ่มลงในรายการข้อมูลในฐานข้อมูล Firebase ทุกครั้งที่เราส่งคำขอ POST ไคลเอ็นต์ Firebase จะสร้างคีย์ที่ไม่ซ้ำกัน เช่น fireblog/users/<unique-id>/<data> |
| ลบ | นำข้อมูลออกจากข้อมูลอ้างอิงฐานข้อมูล Firebase ที่ระบุ |
การเขียนข้อมูลด้วย PUT
การดำเนินการเขียนพื้นฐานผ่าน REST API คือ PUT เพื่อสาธิตการบันทึกข้อมูล เราจะสร้างแอปพลิเคชันบล็อกที่มีโพสต์และผู้ใช้ ข้อมูลทั้งหมดสำหรับแอปพลิเคชันของเราจะจัดเก็บไว้ในเส้นทาง `fireblog` ที่ URL ของฐานข้อมูล Firebase `https://docs-examples.firebaseio.com/fireblog`
มาเริ่มด้วยการบันทึกข้อมูลผู้ใช้บางส่วนลงในฐานข้อมูล Firebase กัน เราจะจัดเก็บผู้ใช้แต่ละรายตามชื่อผู้ใช้ที่ไม่ซ้ำกัน และจะจัดเก็บชื่อนามสกุลและวันเกิดของผู้ใช้ด้วย เนื่องจากผู้ใช้แต่ละรายจะมีชื่อผู้ใช้ที่ไม่ซ้ำกัน จึงควรใช้ PUT ที่นี่แทน POST เนื่องจากเรามีคีย์อยู่แล้วและไม่จำเป็นต้องสร้างคีย์ใหม่
เมื่อใช้ PUT เราสามารถเขียนสตริง, ตัวเลข, บูลีน, อาร์เรย์ หรือออบเจ็กต์ JSON ใดๆ ลงในฐานข้อมูล Firebase ได้ ในกรณีนี้ เราจะส่งออบเจ็กต์ต่อไปนี้
curl -X PUT -d '{
"alanisawesome": {
"name": "Alan Turing",
"birthday": "June 23, 1912"
}
}' 'https://docs-examples.firebaseio.com/fireblog/users.json'
เมื่อบันทึกออบเจ็กต์ JSON ลงในฐานข้อมูล ระบบจะแมปพร็อพเพอร์ตี้ของออบเจ็กต์กับตำแหน่งย่อยโดยอัตโนมัติในลักษณะที่ซ้อนกัน หากไปที่โหนดที่สร้างขึ้นใหม่ เราจะเห็นค่า "Alan Turing" นอกจากนี้ เรายังบันทึกข้อมูลลงในตำแหน่งย่อยได้โดยตรง ดังนี้
curl -X PUT -d '"Alan Turing"' \ 'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome/name.json'
curl -X PUT -d '"June 23, 1912"' \ 'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome/birthday.json'
ตัวอย่าง 2 รายการข้างต้น ซึ่งก็คือการเขียนค่าพร้อมกันเป็นออบเจ็กต์และการเขียนค่าแยกกันไปยังตำแหน่งย่อย จะส่งผลให้มีการบันทึกข้อมูลเดียวกันลงในฐานข้อมูล Firebase ดังนี้
{
"users": {
"alanisawesome": {
"date_of_birth": "June 23, 1912",
"full_name": "Alan Turing"
}
}
}
คำขอที่สำเร็จจะแสดงด้วยรหัสสถานะ HTTP 200 OK และการตอบกลับจะมีข้อมูลที่เราเขียนลงในฐานข้อมูล ตัวอย่างแรกจะทริกเกอร์เหตุการณ์เดียวในไคลเอ็นต์ที่กำลังดูข้อมูล ส่วนตัวอย่างที่ 2 จะทริกเกอร์ 2 เหตุการณ์ โปรดทราบว่าหากมีข้อมูลอยู่ในเส้นทางของผู้ใช้อยู่แล้ว วิธีแรกจะเขียนทับข้อมูลดังกล่าว แต่วิธีที่ 2 จะแก้ไขเฉพาะค่าของโหนดบุตรหลานที่แยกกันแต่ละโหนดโดยไม่เปลี่ยนแปลงบุตรหลานอื่นๆ PUT เทียบเท่ากับ set() ใน JavaScript SDK
การอัปเดตข้อมูลด้วย PATCH
การใช้คำขอ PATCH ช่วยให้เราอัปเดตรายการย่อยที่เฉพาะเจาะจงในตำแหน่งได้โดยไม่ต้องเขียนทับข้อมูลที่มีอยู่ มาเพิ่มชื่อเล่นของ Turing ลงในข้อมูลผู้ใช้ด้วยคำขอ PATCH กัน:
curl -X PATCH -d '{
"nickname": "Alan The Machine"
}' \
'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'
คำขอด้านบนจะเขียน nickname ลงในออบเจ็กต์ alanisawesome โดยไม่ลบออบเจ็กต์ย่อย name หรือ birthday โปรดทราบว่าหากเราส่งคำขอ PUT ที่นี่แทน name และ birthday จะถูกลบเนื่องจากไม่ได้รวมอยู่ในคำขอ ตอนนี้ข้อมูลในฐานข้อมูล Firebase ของเรามีลักษณะดังนี้
{
"users": {
"alanisawesome": {
"date_of_birth": "June 23, 1912",
"full_name": "Alan Turing",
"nickname": "Alan The Machine"
}
}
}
คำขอที่สำเร็จจะแสดงด้วยรหัสสถานะ HTTP 200 OK และการตอบกลับจะมีข้อมูลที่อัปเดตซึ่งเขียนลงในฐานข้อมูล
นอกจากนี้ Firebase ยังรองรับการอัปเดตหลายเส้นทางด้วย ซึ่งหมายความว่าตอนนี้ PATCH สามารถอัปเดตค่าในหลายตำแหน่งในฐานข้อมูล Firebase ได้พร้อมกัน ซึ่งเป็นฟีเจอร์ที่มีประสิทธิภาพที่ช่วยให้คุณดีนอร์มัลไลซ์ข้อมูลได้ เมื่อใช้การอัปเดตแบบหลายเส้นทาง เราจะเพิ่มชื่อเล่นให้กับทั้ง Alan และ Grace พร้อมกันได้ ดังนี้
curl -X PATCH -d '{
"alanisawesome/nickname": "Alan The Machine",
"gracehopper/nickname": "Amazing Grace"
}' \
'https://docs-examples.firebaseio.com/fireblog/users.json'
หลังจากอัปเดตนี้ ทั้ง Alan และ Grace จะมีชื่อเล่นเพิ่มเข้ามา ดังนี้
{
"users": {
"alanisawesome": {
"date_of_birth": "June 23, 1912",
"full_name": "Alan Turing",
"nickname": "Alan The Machine"
},
"gracehop": {
"date_of_birth": "December 9, 1906",
"full_name": "Grace Hopper",
"nickname": "Amazing Grace"
}
}
}โปรดทราบว่าการพยายามอัปเดตออบเจ็กต์โดยการเขียนออบเจ็กต์ที่มีเส้นทางรวมอยู่ด้วยจะส่งผลให้เกิดลักษณะการทำงานที่แตกต่างกัน มาดูกันว่าจะเกิดอะไรขึ้นหากเราพยายามอัปเดต Grace และ Alan ด้วยวิธีนี้แทน
curl -X PATCH -d '{
"alanisawesome": {"nickname": "Alan The Machine"},
"gracehopper": {"nickname": "Amazing Grace"}
}' \
'https://docs-examples.firebaseio.com/fireblog/users.json'
ซึ่งจะส่งผลให้เกิดลักษณะการทำงานที่แตกต่างกัน กล่าวคือ การเขียนทับโหนด /fireblog/users ทั้งหมด
{
"users": {
"alanisawesome": {
"nickname": "Alan The Machine"
},
"gracehop": {
"nickname": "Amazing Grace"
}
}
}การอัปเดตข้อมูลด้วยคำขอแบบมีเงื่อนไข
คุณสามารถใช้คำขอแบบมีเงื่อนไข ซึ่งเป็น REST ที่เทียบเท่ากับธุรกรรม เพื่ออัปเดตข้อมูลตามสถานะที่มีอยู่ ตัวอย่างเช่น หากต้องการเพิ่มตัวนับการโหวตเห็นด้วย และต้องการตรวจสอบว่าจำนวนดังกล่าวแสดงการโหวตเห็นด้วยหลายรายการพร้อมกันอย่างถูกต้อง ให้ใช้คำขอแบบมีเงื่อนไขเพื่อเขียนค่าใหม่ลงในตัวนับ แทนที่จะมีการเขียน 2 ครั้งที่เปลี่ยนตัวนับเป็นตัวเลขเดียวกัน คำขอเขียนรายการใดรายการหนึ่งจะล้มเหลว และคุณสามารถลองส่งคำขออีกครั้งด้วยค่าใหม่ได้- หากต้องการส่งคำขอแบบมีเงื่อนไขที่ตำแหน่งหนึ่งๆ ให้รับตัวระบุที่ไม่ซ้ำกันสำหรับข้อมูลปัจจุบันที่ตำแหน่งนั้น หรือ ETag หากข้อมูลเปลี่ยนแปลงที่ตำแหน่งนั้น ETag ก็จะเปลี่ยนแปลงด้วย คุณสามารถขอ ETag ด้วยเมธอดใดก็ได้นอกเหนือจาก
PATCHตัวอย่างต่อไปนี้ใช้คำขอGET การเรียกใช้ ETag ในส่วนหัวโดยเฉพาะจะแสดงผล ETag ของตำแหน่งที่ระบุในการตอบกลับ HTTPcurl -i 'https://test.example.com/posts/12345/upvotes.json' -H 'X-Firebase-ETag: true'
HTTP/1.1 200 OK Content-Length: 6 Content-Type: application/json; charset=utf-8 Access-Control-Allow-Origin: * ETag: [ETAG_VALUE] Cache-Control: no-cache 10 // Current value of the data at the specified location
- รวม ETag ที่แสดงผลไว้ในคำขอ
PUTหรือDELETEครั้งถัดไปเพื่ออัปเดตข้อมูลที่ตรงกับค่า ETag นั้นโดยเฉพาะ จากตัวอย่างของเรา หากต้องการอัปเดตตัวนับเป็น 11 หรือมากกว่าค่าที่ดึงมาตอนแรก 1 ค่า (ซึ่งก็คือ 10) และทำให้คำขอล้มเหลวหากค่าไม่ตรงกันอีกต่อไป ให้ใช้โค้ดต่อไปนี้ หากค่าของข้อมูลในตำแหน่งที่ระบุยังคงเป็น 10 ค่า ETag ในคำขอcurl -iX PUT -d '11' 'https://[PROJECT_ID].firebaseio.com/posts/12345/upvotes.json' -H 'if-match:[ETAG_VALUE]'
PUTจะตรงกัน และคำขอจะสำเร็จ โดยเขียนค่า 11 ลงในฐานข้อมูล หากตำแหน่งไม่ตรงกับ ETag อีกต่อไป ซึ่งอาจเกิดขึ้นได้หากผู้ใช้รายอื่นเขียนค่าใหม่ลงในฐานข้อมูล คำขอจะล้มเหลวโดยไม่มีการเขียนลงในตำแหน่งดังกล่าว การตอบกลับที่ส่งคืนจะมีค่าใหม่และ ETagHTTP/1.1 200 OK Content-Length: 6 Content-Type: application/json; charset=utf-8 Access-Control-Allow-Origin: * Cache-Control: no-cache 11 // New value of the data at the specified location, written by the conditional request
HTTP/1.1 412 Precondition Failed Content-Length: 6 Content-Type: application/json; charset=utf-8 Access-Control-Allow-Origin: * ETag: [ETAG_VALUE] Cache-Control: no-cache 12 // New value of the data at the specified location
- ใช้ข้อมูลใหม่หากคุณตัดสินใจที่จะลองส่งคำขออีกครั้ง Realtime Database จะไม่ลองส่งคำขอแบบมีเงื่อนไขที่ดำเนินการไม่สำเร็จอีกครั้งโดยอัตโนมัติ อย่างไรก็ตาม คุณสามารถใช้ค่าใหม่และ ETag เพื่อสร้างคำขอแบบมีเงื่อนไขใหม่ด้วยข้อมูลที่แสดงโดยการตอบกลับที่ล้มเหลว
คำขอแบบมีเงื่อนไขที่อิงตาม REST จะใช้มาตรฐาน HTTP if-match อย่างไรก็ตาม โฆษณาเหล่านี้แตกต่างจากโฆษณามาตรฐานในลักษณะต่อไปนี้
- คุณระบุค่า ETag ได้เพียงค่าเดียวสำหรับคำขอ if-match แต่ละรายการ โดยจะระบุหลายค่าไม่ได้
- แม้ว่ามาตรฐานจะแนะนำให้แสดงผล ETag พร้อมกับคำขอทั้งหมด แต่ Realtime Database จะแสดงผล ETag พร้อมกับคำขอที่มีส่วนหัว
X-Firebase-ETagเท่านั้น ซึ่งจะช่วยลดค่าใช้จ่ายที่เรียกเก็บสำหรับคำขอมาตรฐาน
นอกจากนี้ คำขอแบบมีเงื่อนไขอาจช้ากว่าคำขอ REST ทั่วไป
การบันทึกรายการข้อมูล
หากต้องการสร้างคีย์ตามการประทับเวลาที่ไม่ซ้ำกันสำหรับโหนดบุตรหลานทุกโหนดที่เพิ่มลงในการอ้างอิงฐานข้อมูล Firebase เราสามารถส่งคำขอ POST ได้ สำหรับเส้นทาง users เราควรกำหนดคีย์ของเราเองเนื่องจากผู้ใช้แต่ละรายมีชื่อผู้ใช้ที่ไม่ซ้ำกัน แต่เมื่อผู้ใช้เพิ่มบล็อกโพสต์ลงในแอป เราจะใช้คำขอ POST เพื่อสร้างคีย์สำหรับบล็อกโพสต์แต่ละรายการโดยอัตโนมัติ ดังนี้
curl -X POST -d '{
"author": "alanisawesome",
"title": "The Turing Machine"
}' 'https://docs-examples.firebaseio.com/fireblog/posts.json'
ตอนนี้เส้นทาง posts มีข้อมูลต่อไปนี้
{
"posts": {
"-JSOpn9ZC54A4P4RoqVa": {
"author": "alanisawesome",
"title": "The Turing Machine"
}
}
}
โปรดทราบว่าระบบสร้างคีย์ -JSOpn9ZC54A4P4RoqVa ให้เราโดยอัตโนมัติเนื่องจากเราใช้คำขอ POST คำขอที่สำเร็จจะแสดงด้วยรหัสสถานะ HTTP 200 OK และการตอบกลับจะมีคีย์ของข้อมูลใหม่ที่เพิ่มเข้ามา ดังนี้
{"name":"-JSOpn9ZC54A4P4RoqVa"}กำลังนำข้อมูลออก
หากต้องการนำข้อมูลออกจากฐานข้อมูล เราสามารถส่งคำขอ DELETE พร้อม URL ของเส้นทางที่เราต้องการลบข้อมูล คำสั่งต่อไปนี้จะลบ Alan ออกจากเส้นทาง users ของเรา
curl -X DELETE \ 'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'
คำขอ DELETE ที่สำเร็จจะแสดงด้วยรหัสสถานะ HTTP 200 OK พร้อมการตอบกลับที่มี JSON null
พารามิเตอร์ URI
REST API ยอมรับพารามิเตอร์ URI ต่อไปนี้เมื่อเขียนข้อมูลลงในฐานข้อมูล
การตรวจสอบสิทธิ์
พารามิเตอร์คำขอ auth ช่วยให้เข้าถึงข้อมูลที่ได้รับการปกป้องโดย Firebase Realtime Database Security Rules และคำขอทุกประเภทจะรองรับพารามิเตอร์นี้ อาร์กิวเมนต์อาจเป็นข้อมูลลับของแอป Firebase หรือโทเค็นการตรวจสอบสิทธิ์ ซึ่งเราจะพูดถึงในส่วนการให้สิทธิ์ผู้ใช้ ในตัวอย่างต่อไปนี้ เราจะส่งคำขอ POST พร้อมพารามิเตอร์ auth โดยที่ CREDENTIAL เป็น Firebase App Secret หรือโทเค็นการตรวจสอบสิทธิ์
curl -X POST -d '{"Authenticated POST request"}' \
'https://docs-examples.firebaseio.com/auth-example.json?auth=CREDENTIAL'
พิมพ์
พารามิเตอร์ print ช่วยให้เราระบุรูปแบบการตอบกลับจากฐานข้อมูลได้ การเพิ่ม print=pretty ลงในคำขอจะแสดงข้อมูลในรูปแบบที่มนุษย์อ่านได้ print=pretty ได้รับการสนับสนุนจากคำขอ GET, PUT, POST, PATCH และ DELETE รายการ
หากต้องการระงับเอาต์พุตจากเซิร์ฟเวอร์เมื่อเขียนข้อมูล เราสามารถเพิ่ม print=silent ลงในคำขอได้ การตอบกลับที่ได้จะว่างเปล่าและระบุด้วยรหัสสถานะ HTTP 204 No Content หากคำขอสำเร็จ
print=silent รองรับคำขอ GET, PUT, POST และ PATCH
การเขียนค่าเซิร์ฟเวอร์
คุณสามารถเขียนค่าเซิร์ฟเวอร์ที่ตำแหน่งได้โดยใช้ค่าตัวยึดตำแหน่ง ซึ่งเป็นออบเจ็กต์ที่มีคีย์ ".sv" รายการเดียว ค่าของคีย์นั้นคือประเภทค่าของเซิร์ฟเวอร์ที่เราต้องการตั้งค่า
ตัวอย่างเช่น หากต้องการตั้งค่าการประทับเวลาเมื่อสร้างผู้ใช้ เราสามารถทำดังนี้
curl -X PUT -d '{".sv": "timestamp"}' \
'https://docs-examples.firebaseio.com/alanisawesome/createdAt.json'
"timestamp" เป็นค่าเซิร์ฟเวอร์เดียวที่รองรับ และเป็นเวลาตั้งแต่ Unix Epoch ในหน่วยมิลลิวินาที
การปรับปรุงประสิทธิภาพการเขียน
หากเราเขียนข้อมูลจำนวนมากไปยังฐานข้อมูล เราสามารถใช้พารามิเตอร์ print=silent เพื่อปรับปรุงประสิทธิภาพการเขียนและลดการใช้แบนด์วิดท์ได้ ในลักษณะการเขียนปกติ เซิร์ฟเวอร์จะตอบกลับด้วยข้อมูล JSON ที่เขียน
เมื่อระบุ print=silent เซิร์ฟเวอร์จะปิดการเชื่อมต่อทันทีเมื่อได้รับข้อมูล ซึ่งจะช่วยลดการใช้แบนด์วิดท์
ในกรณีที่เราส่งคำขอจำนวนมากไปยังฐานข้อมูล เราสามารถใช้การเชื่อมต่อ HTTPS ซ้ำได้โดยส่งคำขอ Keep-Alive ในส่วนหัว HTTP
เงื่อนไขข้อผิดพลาด
REST API จะแสดงรหัสข้อผิดพลาดในกรณีต่อไปนี้
| รหัสสถานะ HTTP | |
|---|---|
| 400 คำขอไม่ถูกต้อง |
เงื่อนไขข้อผิดพลาดอย่างใดอย่างหนึ่งต่อไปนี้
|
| 401 ไม่ได้รับอนุญาต |
เงื่อนไขข้อผิดพลาดอย่างใดอย่างหนึ่งต่อไปนี้
|
| 404 Not Found | ไม่พบฐานข้อมูล Firebase ที่ระบุ |
| 500 ข้อผิดพลาดภายในเซิร์ฟเวอร์ | เซิร์ฟเวอร์แสดงข้อผิดพลาด ดูรายละเอียดเพิ่มเติมได้ในข้อความแสดงข้อผิดพลาด |
| 503 ไม่พร้อมให้บริการ | ฐานข้อมูลเรียลไทม์ของ Firebase ที่ระบุไม่พร้อมใช้งานชั่วคราว ซึ่งหมายความว่าระบบไม่ได้พยายามส่งคำขอ |
การรักษาความปลอดภัยของข้อมูล
Firebase มีภาษาด้านความปลอดภัยที่ช่วยให้เรากำหนดได้ว่าผู้ใช้รายใดมีสิทธิ์อ่านและเขียนในโหนดต่างๆ ของข้อมูล อ่านข้อมูลเพิ่มเติมได้ใน Realtime Database Security Rules
เมื่อเราได้พูดถึงการบันทึกข้อมูลแล้ว เราจะเรียนรู้วิธีดึงข้อมูลจากฐานข้อมูล Firebase ผ่าน REST API ในส่วนถัดไป