39 Skema Filter & Pagination: Best Practice
Filter dan pagination adalah dua topik krusial dalam pengembangan aplikasi web modern. Akhir-akhir ini, kebutuhan pengolahan data dalam jumlah besar kian meningkat, entah itu data produk di e-commerce, data artikel, user, log aktivitas, maupun resources API lain. Koneksi API efisien, pengalaman pengguna optimal, hingga resource back-end pun bergantung pada skema filter & pagination yang diterapkan. Oleh karena itu, sangat penting memahami best practices dan skema implementasi yang tepat.
Pada artikel ini, saya akan membahas 39 skema filter & pagination paling umum, mengulas best practice yang perlu Anda pahami, serta menampilkan contoh kode, simulasi respon API, hingga diagram alur (menggunakan mermaid
). Meskipun secara harfiah ada puluhan variasi skema, kita akan ulas yang paling relevan yang sering ditemukan di dunia nyata.
Mengapa Filter & Pagination itu Penting?
Dalam aplikasi berbasis REST maupun GraphQL, tanpa pagination atau filter, endpoint akan mengembalikan entire dataset yang jelas tidak efisien (bahkan mematikan sistem!). Pengguna hanya ingin sebagian hasil, dengan kriteria spesifik — inilah peran filter & pagination.
Manfaat:
- Respons Lebih Cepat: Query hanya subset data.
- Penghematan Bandwidth: Transfer data hanya yang benar-benar dibutuhkan.
- UX Lebih Baik: Navigasi data lebih nyaman.
- Menghindari Overload Database: Query jadi lebih ringan.
39 Skema Filter & Pagination
Skema berikut dikategorikan berdasarkan filter, pagination, dan kombinasi keduanya.
I. Skema Filter (14)
Query String Basic
Contoh:GET /products?category=shoes&color=black
Semudah menambahkan parameter pada URL.Filter Operator Lanjutan
Misal:GET /users?age[gt]=18&age[lt]=45
Multiple Values (Array Query)
GET /posts?tags=tech,devops,cloud
Exclude Filter
GET /books?exclude_status=archived
Range (Between)
GET /sales?date_from=2024-01-01&date_to=2024-01-31
Partial Match
GET /contacts?name_like=adam
IN/NOT IN
GET /id_list?user_id[in]=1,2,3
Nested Object Filter
GET /orders?customer.address.city=Jakarta
Boolean Filter
GET /items?active=true
Case Sensitive/Insensitive
GET /customers?email__iexact=gmail.com
Regex Filtering
GET /files?name_regex=^foo
Null/Not Null
GET /payment?receipt_number[null]=true
Sorting
GET /products?sort=price,-name
Aggregation Filtering
GET /teams?member_count[gt]=5
II. Skema Pagination (13)
Offset-Limit
GET /posts?offset=0&limit=10
Klasik, mudah, tapi bermasalah pada data besar/berubah.
Page-Size
GET /items?page=1&size=25
Cursor-based Pagination
GET /products?after=YXNkMTIz&limit=10
Lebih reliabel pada data sering berubah.
Seek Method
GET /comments?last_id=2024&limit=10
Keyset Based
- Mirip seek, gunakan unique field (
createdAt
,id
, dsb.).
- Mirip seek, gunakan unique field (
Time-based Keyset
- Pagination berdasarkan timestamp.
Backward Pagination (previous)
- Mendukung navigasi balik.
GET /orders?before=...
Range Pagination
- Pakai rentang:
GET /logs?from=567&to=577
- Pakai rentang:
Bookmarked/Custom Cursor
- Support bookmark untuk jump ke posisi tertentu.
Numbered Link Response
- API memberi numbered links: prev, next, first, last.
Infinite Scroll Support
- Untuk aplikasi mobile/spa dengan endless scroll.
Page Token
- Google APIs:
GET /videos?pageToken=abc123
- Google APIs:
Relational Pagination
- Pagination dalam subresource.
III. Kombinasi & Extended Skema (12)
Filter + Pagination
- Umum:
GET /products?category=shoes&limit=10&offset=0
- Umum:
Filter + Sort + Paginate
- Semuanya digabung.
Aggregated Pagination
- Sambil menghitung summary data.
Stateless Cursor
- Cursor tidak menyimpan state user.
Stateful Cursor
- State khusus tiap user/role.
Caching-aware Pagination
- Pagination tetap konsisten saat data cache berubah.
Pre-Fetch Pagination
- Memproses 2 page sekaligus untuk user experience.
Chunked Pagination
- Menyertakan data “hint” total chunks/pages.
Meta-based Pagination
- Response berisi meta object:
{ "data": [...], "meta": { "pagination": { "page": 1, "total": 99 } } }
- Response berisi meta object:
GraphQL Connection Pattern
- edges, nodes, pageInfo.
Custom Encrypted Tokens
- Cursors dalam bentuk encrypted blob.
Slicing, Windowing, Partitioning
- Data diambil per-slice (window), biasanya pada OLAP/BI API.
Best Practice Filter & Pagination
Mari kita bahas best practices yang menurut saya wajib diadopsi:
- Kombinasikan Filter, Sort, dan Pagination — Hampir semua kebutuhan nyata membutuhkan tiga ini sekaligus.
- Default Limit yang Wajar — Selalu tetapkan default limit dan maximum limit per page (misal max 100).
- Gunakan Cursor untuk Data yang Cepat Berubah — Cursor-based jauh lebih andal pada tabel berubah cepat.
- Dokumentasi Parameter — Daftarkan filter/sort field yang valid di dokumentasi API kamu, termasuk operator/field.
- Meta Pagination Info — Sertakan total data/page jika performa memungkinkan, untuk memudahkan frontend.
- Consistent Responses — Response schema (field, meta, structure) harus konsisten.
- Jangan Support Filter Siluman — Filterlah hanya pada field yang sudah di-query/index di database.
- Handle Input Error — Validasi input (misal
limit
tidak lebih dari max, filter field harus valid). - Biarkan Kombinasi Filter Multivalue — Filter array dan operator OR/AND penting untuk advanced search.
- Paginate API Response, Bukan Query DB — Biasakan mem-paginate hasil query, bukan seluruh tabel.
Diagram Alur Pagination (Offset vs Cursor)
Mari kita bandingkan offset vs cursor:
flowchart TD Start([Start Request]) --> CheckType{Pagination Type?} CheckType -- Offset-Based --> OffsetDB[Query DB dengan OFFSET dan LIMIT] CheckType -- Cursor-Based --> WhereCursor[WHERE id > last_id ORDER BY id LIMIT N] OffsetDB --> RespOffset[Build & Send Response] WhereCursor --> RespCursor[Build & Send Response (with next cursor)] RespOffset --> End RespCursor --> End
Catatan Singkat:
- Offset:
Sederhana, namun lambat untuk data sangat besar (karena DB harus skip N rows). - Cursor:
Lebih efisien ketika data berubah (insert/delete), lebih cocok untuk infinite scroll.
Simulasi Response Pagination
Offset-based
{
"data": [{ "id": 101, "title": "Item 1" }, ...],
"meta": {
"page": 1,
"limit": 10,
"total": 99
}
}
Cursor-based
{
"data": [{ "id": 121, "title": "Item 21" }, ...],
"next_cursor": "e2lkOjEyMSxjcmVhdGVkQXQ6dGltZXN0YW1w",
"has_next_page": true
}
Contoh Kode: Implementasi Pagination & Multi-Filter (Node.js + Express + Prisma)
app.get("/api/users", async (req, res) => {
const { page = 1, size = 20, sort = "id", order = "asc", name, age_gt, age_lt } = req.query;
const where = {};
if (name) where.name = { contains: name, mode: 'insensitive' };
if (age_gt) where.age = { ...where.age, gt: Number(age_gt) };
if (age_lt) where.age = { ...where.age, lt: Number(age_lt) };
const [data, total] = await Promise.all([
prisma.user.findMany({
where,
skip: (page - 1) * size,
take: Number(size),
orderBy: { [sort]: order }
}),
prisma.user.count({ where })
]);
return res.json({
data,
meta: {
page: Number(page),
size: Number(size),
total
}
});
});
Tabel: 39 Skema (Ringkasan)
Kategori | Skema (Contoh) | Kapan Digunakan |
---|---|---|
Filter | Partial match, in, range | User search/filtering |
Pagination | Offset, cursor, token | List, Infinite scroll, Large dataset |
Kombinasi | Filter+Sort+Paginate | Dashboard, advanced search |
Extended | Aggregated, windowing | Analytics, OLAP, reporting |
Tips & Antipattern
- Antipattern:
limit=1000
tanpa validasi → akan membunuh resource DB. - Jangan leak data internal: Jangan izinkan filter pada field sensitif, misal
hashed_password
. - Gunakan Index pada field yang paling sering digunakan sebagai filter & sort.
- Cek hasil filter: Data kosong juga harus tetap success (return
[]
, bukan error).
Penutup
Memilih dan mengimplementasikan skema filter & pagination yang tepat bisa sangat menentukan scaling, performa, dan kemudahan pengembangan aplikasi Anda. Kuasai 39 variasi skema di atas, pilih yang paling sesuai dengan konteks bisnis, dan pastikan user experience menjadi prioritas.
Bagikan pengalaman skema filter & pagination yang menurutmu paling efektif di kolom komentar! 🚀
61. Load Balancing di gRPC Client
Artikel Terhangat
41 Pengenalan Unit Test untuk Resolver
08 Aug 2025
63. gRPC Health Checking Standar
08 Aug 2025
39 Skema Filter & Pagination: Best Practice
08 Aug 2025
61. Load Balancing di gRPC Client
08 Aug 2025

41 Pengenalan Unit Test untuk Resolver

63. gRPC Health Checking Standar

39 Skema Filter & Pagination: Best Practice
