วิธีประหยัดอินเทอร์เน็ต |
|
---|---|
PUT | เขียนหรือแทนที่ข้อมูลในเส้นทางที่กําหนด เช่น fireblog/users/user1/<data> |
แผ่นแปะ | อัปเดตคีย์บางรายการสำหรับเส้นทางที่กําหนดไว้โดยไม่ต้องแทนที่ข้อมูลทั้งหมด |
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" } } }
คำขอที่สำเร็จจะแสดงด้วย200 OK
รหัสสถานะ HTTP และการตอบกลับจะมีข้อมูลที่เราได้เขียนลงในฐานข้อมูล ตัวอย่างแรกจะทริกเกอร์เหตุการณ์เพียง 1 รายการในไคลเอ็นต์ที่ดูข้อมูลอยู่ ส่วนตัวอย่างที่ 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 หรือมากกว่าค่าที่ดึงข้อมูลครั้งแรก 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 ใช้มาตรฐาน HTTPif-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 หรือโทเค็นการตรวจสอบสิทธิ์
curl -X POST -d '{"Authenticated POST request"}' \ 'https://docs-examples.firebaseio.com/auth-example.json?auth=CREDENTIAL'
พิมพ์
พารามิเตอร์ print
ช่วยให้เราระบุรูปแบบของคำตอบจากฐานข้อมูลได้ การเพิ่ม print=pretty
ลงในคําขอจะแสดงผลข้อมูลในรูปแบบที่มนุษย์อ่านได้ คำขอ GET
, PUT
, POST
, PATCH
และ DELETE
รองรับ print=pretty
หากต้องการซ่อนเอาต์พุตจากเซิร์ฟเวอร์เมื่อเขียนข้อมูล เราเพิ่ม print=silent
ลงในคำขอได้ การตอบกลับที่ได้จะว่างเปล่าและระบุด้วยรหัสสถานะ HTTP 204 No Content
หากคำขอสำเร็จ
คำขอ GET
, PUT
, POST
และ PATCH
รองรับ print=silent
การเขียนค่าเซิร์ฟเวอร์
ค่าเซิร์ฟเวอร์สามารถเขียนไว้ในตำแหน่งโดยใช้ค่าตัวยึดตําแหน่ง ซึ่งเป็นออบเจ็กต์ที่มีคีย์ ".sv"
รายการเดียว ค่าของคีย์นั้นคือประเภทของค่าเซิร์ฟเวอร์ที่เราต้องการตั้งค่า
เช่น หากต้องการตั้งการประทับเวลาเมื่อสร้างผู้ใช้ เราอาจทําดังนี้
curl -X PUT -d '{".sv": "timestamp"}' \ 'https://docs-examples.firebaseio.com/alanisawesome/createdAt.json'
"timestamp"
เป็นค่าเซิร์ฟเวอร์เพียงค่าเดียวที่รองรับ และเป็นเวลาที่นับจากยุค UNIX เป็นมิลลิวินาที
การปรับปรุงประสิทธิภาพการเขียน
หากเขียนข้อมูลจำนวนมากลงในฐานข้อมูล เราจะใช้พารามิเตอร์ print=silent
เพื่อปรับปรุงประสิทธิภาพการเขียนและลดการใช้แบนด์วิดท์ได้ ในลักษณะการเขียนปกติ เซิร์ฟเวอร์จะตอบกลับด้วยข้อมูล JSON ที่เขียน
เมื่อระบุ print=silent
เซิร์ฟเวอร์จะปิดการเชื่อมต่อทันทีที่ได้รับข้อมูล ซึ่งจะช่วยลดการใช้แบนด์วิดท์
ในกรณีที่มีการส่งคำขอไปยังฐานข้อมูลหลายรายการ เราจะใช้การเชื่อมต่อ HTTPS ซ้ำได้โดยส่งคำขอ Keep-Alive
ในส่วนหัว HTTP
เงื่อนไขข้อผิดพลาด
REST API จะแสดงรหัสข้อผิดพลาดในกรณีต่อไปนี้
รหัสสถานะ HTTP | |
---|---|
400 คำขอไม่ถูกต้อง |
เงื่อนไขข้อผิดพลาดอย่างใดอย่างหนึ่งต่อไปนี้
|
401 ไม่ได้รับอนุญาต |
เงื่อนไขข้อผิดพลาดอย่างใดอย่างหนึ่งต่อไปนี้
|
404 ไม่พบ | ไม่พบฐานข้อมูล Firebase ที่ระบุ |
500 ข้อผิดพลาดภายในเซิร์ฟเวอร์ | เซิร์ฟเวอร์แสดงข้อผิดพลาด โปรดดูรายละเอียดเพิ่มเติมในข้อความแสดงข้อผิดพลาด |
503 ไม่พร้อมให้บริการ | ฐานข้อมูลเรียลไทม์ของ Firebase ที่ระบุไม่พร้อมใช้งานชั่วคราว ซึ่งหมายความว่าไม่มีการพยายามส่งคำขอ |
การรักษาความปลอดภัยของข้อมูล
Firebase มีภาษาด้านความปลอดภัยที่ช่วยให้เรากําหนดได้ว่าผู้ใช้รายใดมีสิทธิ์อ่านและเขียนโหนดข้อมูลต่างๆ อ่านข้อมูลเพิ่มเติมได้ใน Realtime Database Security Rules
เมื่อพูดถึงการบันทึกข้อมูลแล้ว เรามาเรียนรู้วิธีดึงข้อมูลจากฐานข้อมูล Firebase ผ่าน REST API กันต่อในส่วนถัดไป