Pagination ขั้นเทพสไตล์ Facebook Graph API (Part 1/2)

Thirajade Lekkunlawat
Grean Developers Family
3 min readMay 25, 2019

สวัสดีครับทุกๆท่าน ห่างหายกันไปนานเลย สำหรับวันนี้ผมก็มาพร้อมๆกับเรื่อง pagination นั่นเอง หลายๆคนคงเคยได้ยินมาบ้าง หรือ อาจจะเคยทำมาแล้วเลยด้วย วันนี้เราจะมาอธิบายคอนเซ็ปต์ของ pagination ในแต่ละแบบ และดูว่า facebook ใช้แบบไหนอย่างไรบ้าง ไปดูกันเล้ยยยยยย

Pagination คือ?

pagination เนี่ยคือการแบ่ง response ของ API ออกเป็น page หรือเป็นหน้าๆนั่นเอง เพื่อให้ข้อมูลที่ API คืนค่ามานั้นไม่เยอะจนเกินไป ยกตัวอย่างเช่นเวลาเราค้นหาอะไรก็แล้วแต่ในกูเกิลเนี่ย ด้านล่างสุดเราจะเห็นแบบนี้

pagination ของ google

ภาพด้านบนนี่ก็เป็น pagination ชนิดหนึ่ง ในการแบ่ง response ออกเป็นหลายๆหน้านั่นเองครับ

ชนิดของ Pagination

pagination ปัจจุบันจะมีอยู่ 3 ชนิดได้แก่

  1. Offset-based Pagination
  2. Cursor-based Pagination
  3. Time-based Pagination

เดี๋ยวเราจะมาลงรายละเอียดกันเลยว่า pagination แต่ละแบบเนี่ยมันเป็นยังไงกันแน่ แล้วแต่ละแบบมีข้อดีข้อเสียอย่างไรบ้าง ซึ่งอันที่เฟสบุคใช้เนี่ย ก็คือ pagination ในข้อ 2 กับ 3 ครับ

Offset-based Pagination

อันนี้เรียกว่าเป็น pagination แบบเบสิคที่สุดเลย เป็นการ pagination โดยใช้ offset หรือง่ายๆก็คือ เลข page นั่นแหล่ะ จะเป็น page 1,2,3 หรือ 4 อะไรก็ว่าไป และมีการระบุด้วยว่า page นึงจะให้มีข้อมูลกี่ record เช่น ตัวอย่างรูปกูเกิลด้านบนนั่นคือการทำ Offset-based pagination นั่นเองครับ

รูปภาพด้านล่างนี้แสดงให้เห็นถึงในกรณีที่เรา request โดยระบุ limit เป็น 3 แล้วใส่ page เป็นอะไรก็แล้วแต่ ก็จะได้ข้อมูลตามกรอบของ page นั้นๆไปนั่นเองครับ

offset-based pagination

แล้วมันไม่ดียังไง??

จริงๆแล้ว Offset-based pagination ก็ไม่ใช่ว่าไม่ดีนะครับ เพียงแต่ว่าใน product บางประเภทเนี่ย การทำ pagination แบบนี้ไม่ตอบโจทย์เช่น product ที่มีข้อมูลไหลเข้ามาเป็น input อยู่ตลอดเวลา ถ้าเราใช้ Offset-based pagination กับ product ประเภทนี้ จะทำให้ user เห็นข้อมูลซ้ำกันได้ ยกตัวอย่างเช่น New Feed ของ Facebook นั่นเอง ก็อาจจะยังไม่เห็นภาพอีกว่ามันเป็นยังไง งั้นเรามาดูกัน step-by-step กับภาพด้านล่างดีกว่าครับ

แสดง step การ request ข้อมูลจาก page 1 ไป page 2

ลองจินตนาการตามทีละ step นะครับ เริ่มจาก

Step 1 — User ขอข้อมูลที่ page=1 และ limit=3 จึงได้ข้อมูล 11, 10, 9 ไป

Step 1.5 — ก่อนที่จะถึง step 2 เนี่ย ดั้นนน ดันมีข้อมูลใหม่เพิ่มเข้ามาซะอย่างนั้น pagination ที่เป็น offset ของเรามันเลยเลื่อนตามภาพ page 1 จะมีข้อมูล 12, 11, 10 แทน แต่ก็ยังไม่มีปัญหา เพราะ user ยังไม่ได้ request มาใหม่

Step 2 — ความหายนะมาเยือนที่จังหวะนี้นั่นเองครับ เมื่อ user ขอข้อมูลที่ page = 2 และ limit = 3 ทำให้ user ได้ข้อมูล 9,8,7 แต่เอ๊ะ?! ข้อมูล 9 เนี่ย user เคยได้ไปแล้วรอบนึงนี่นา กลายเป็นว่าได้ข้อมูลซ้ำซะอย่างนั้น

เพราะฉะนั้น การทำ Offset-based pagination จึงไม่เหมาะกับ product ชนิดที่มี input เข้ามาใหม่ตลอดเวลานั่นเองครับ
นั่นจึงเป็นที่มาของ 2 วิธีการ pagination ถัดไป

Cursor-based Pagination

Pagination ชนิดนี้จะมีความซับซ้อนขึ้นมาเล็กน้อยโดยที่เราจะไม่มีตัวเลข page 1,2,3 หรืออื่นๆแล้ว แต่ว่าเราจะใช้สิ่งที่เรียกว่า cursor ในการระบุตำแหน่งของข้อมูลที่เราจะ requestแทน แล้วจะทำการส่งข้อมูลกลับมาเป็น next ของ cursor (ข้อมูลชุดถัดไป) หรือ previous ของ cursor (ข้อมูลชุดก่อนหน้า) ก็แล้วแต่เราเลือกเลยครับ

โดย cursor จะมีข้อแม้อยู่ก็คือจะต้อง Unique ห้ามมีค่าซ้ำกันใน Database ของเรา

อ่านแล้วอาจจะงง มาดูรูปด้านล่างกันดีกว่าครับ

Cursor-based Pagination

จากรูปด้านบน การขอข้อมูลครั้งแรก เราจะได้ข้อมูลชุดแรกสุดมา นั่นก็คือ 11,10,9 พร้อมกับ next cursor ที่เป็น 9 นั่นเอง และเมื่อขอข้อมูลชุดถัดไป เราก็จะใช้ next cursor ที่เป็น 9 นั้น อ้างอิงและได้ค่า 8,7,6 มา พร้อมกับ cursor ชุดใหม่ ที่มีทั้ง previous cursor และ next cursor นั่นเองครับ

previous cursor ใช้อ้างอิงเพื่อขอข้อมูลชุดก่อนหน้า ส่วน next cursor ก็ใช้อ้างอิงเพื่อขอข้อมูลชุดถัดไปนั่นเองครับ

แล้วมันมาแก้ปัญหาของ Offset-based Pagination ยังไง?

เนื่องจากว่าเราใช้ cursor ในการอ้างอิงข้อมูล เพราะฉะนั้น ไม่ว่าข้อมูลมีเพิ่มมาแค่ไหน cursor เราก็จะอยู่ที่จุดอ้างอิงจุดเดิม และเมื่อขอข้อมูลครั้งถัดไปก็จะไม่ได้ข้อมูลที่ซ้ำกันอย่างแน่นอน เรามาดู step-by-step กันอีกรอบเลยครับ

แสดง step การ request ข้อมูลจาก page แรก ไป page ถัดไป

Step 1 — User ขอข้อมูลที่ page แรกและระบุlimit=3 จึงได้ข้อมูล 11, 10, 9 ไป

Step 1.5 — มีข้อมูลใหม่ คือ 12 ไม่มีผลอะไร next cursor ยังอยู่ที่ 9 เหมือนเดิม

Step 2 — User ขอข้อมูลถัดไป จึงได้ข้อมูล 8,7,6 พร้อมกับ previous cursor และ next cursor กลับไปอย่างถูกต้อง ไม่มีข้อมูลที่ซ้ำกันจากการขอข้อมูลใน step 1

เห็นไหมครับ แค่นี้เราก็ไม่ได้ข้อมูลที่ซ้ำกันแล้ว

ตัวอย่างจาก Facebook Graph API

ขอยกตัวอย่างจาก Facebook Graph API สักหนึ่งตัวอย่างละกันครับ นั่นคือ API Photos ซึ่งใช้สำหรับขอข้อมูลรูปภาพของเรานั่นแหล่ะ

ให้สังเกตส่วนล่างสุดของ response ครับ จะมี field “paging” ที่มี “cursors” อยู่ และมี next ซึ่งเป็น URL สำหรับข้อมูลชุดถัดไปอยู่ด้วยนั่นเอง โดยที่สามารถใช้ URL ที่อยู่ใน next ได้เลย

API Photos ของ Facebook Graph API

ใครที่สนใจสามารถไปลองเล่น API ของ Facebook ได้ที่ลิงค์นี้เลยนะครับ https://developers.facebook.com/tools/explorer/

บทสรุปสำหรับ Part 1

Pagination ทั้งสองรูปแบบที่ได้อธิบายไปก็น่าจะพอเห็นไอเดียว่า pagination แต่ละรูปแบบจะนำไปใช้กับ product แนวไหน ส่วน Time-based Pagination จะขอมาต่อใน Part ถัดไป หวังว่าจะยังติดตามกันอยู่นะคร้าบ

ถ้ามีส่วนไหนสงสัย หรือแนะนำเพิ่มเติมสามารถคอมเม้นได้เลยนะครับ จะยินดีมากครับถ้าคอมเม้น

สำหรับวันนี้ก็ขอลาไปก่อนสวัสดีคร้าบ

--

--