วิธีประหยัดอินเทอร์เน็ต |
|
---|---|
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
ลงในคำขอได้ การตอบกลับที่ได้จะว่างเปล่าและระบุด้วย204 No Content
รหัสสถานะ HTTP หากคําขอสําเร็จ
คำขอ 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 กันต่อในส่วนถัดไป