POST /read
Spesifikasi endpoint read untuk mengambil daftar record dengan filter
Endpoint /read adalah endpoint universal untuk mengambil data dari database dengan dukungan paginasi, filter WHERE kompleks, pencarian, dan pengurutan.
Referensi Cepat (Quick Reference)
| Properti | Nilai |
|---|---|
| Method | POST |
| URL | /api/{project}/{endpoint}/read |
| Content-Type | application/json |
| Status Sukses | 200 OK |
| Database | PostgreSQL, MySQL, Oracle |
| Cache | Redis (key rf:{project}:{endpoint}:list:{hash}) |
| Default Scope | Diterapkan jika dikonfigurasi di payload |
| Mode Operasi | Paginasi dan non-paginasi |
Ikhtisar (Overview)
Endpoint /read menyediakan dua mode operasi yang ditentukan oleh keberadaan parameter page dalam request body. Mode paginasi mengembalikan metadata halaman lengkap, sementara mode non-paginasi mengembalikan data sekaligus dengan batasan jumlah record.
Endpoint ini mendukung cache Redis untuk meningkatkan performa. Hasil query di-cache berdasarkan hash dari seluruh parameter request, sehingga request yang identik akan dilayani dari cache tanpa query ulang ke database.
Mode Operasi (Operation Modes)
| Mode | Kondisi Aktivasi | Perilaku |
|---|---|---|
| Paginasi | Parameter page dikirim | Mengembalikan data per halaman beserta metadata paginasi (current_page, total_records, total_pages, dll.) |
| Non-paginasi | Parameter page tidak dikirim | Mengembalikan seluruh data sekaligus, dibatasi oleh parameter limit (default: 1000, maks: 5000) |
Format Request (Request Format)
Parameter (Parameters)
| Parameter | Tipe | Wajib | Keterangan |
|---|---|---|---|
page | number | Tidak | Nomor halaman (mengaktifkan mode paginasi) |
per_page | number | Tidak | Jumlah record per halaman (1-100, default: 10) |
limit | number | Tidak | Batas record di mode non-paginasi (1-5000, default: 1000) |
select | array | Tidak | Kolom spesifik yang akan dikembalikan |
search_value | string | Tidak | Kata kunci pencarian (menggunakan LIKE) |
search_by | string | Tidak | Kolom target pencarian |
sort_columns | array | Tidak | Array object { "column": "nama", "direction": "ASC" } |
where | object | Tidak | Kondisi WHERE kompleks dengan operator dan logika AND/OR |
Contoh Request (Request Examples)
Mode paginasi dengan pencarian dan pengurutan:
{
"page": 1,
"per_page": 10,
"search_value": "Jakarta",
"search_by": "city",
"sort_columns": [
{ "column": "supplier_name", "direction": "ASC" }
]
}Mode non-paginasi dengan seleksi kolom:
{
"limit": 100,
"select": ["supplier_id", "supplier_code", "supplier_name"]
}Mode paginasi dengan WHERE kompleks:
{
"page": 1,
"per_page": 20,
"where": {
"logic": "AND",
"conditions": [
{ "key": "city", "operator": "=", "value": "Jakarta" },
{ "key": "is_active", "operator": "=", "value": true },
{ "key": "credit_limit", "operator": ">=", "value": 50000000 }
]
}
}WHERE dengan operator BETWEEN dan IN:
{
"page": 1,
"per_page": 10,
"where": {
"logic": "AND",
"conditions": [
{ "key": "created_at", "operator": "BETWEEN", "value": ["2026-01-01", "2026-12-31"] },
{ "key": "city", "operator": "IN", "value": ["Jakarta", "Surabaya", "Bandung"] }
]
},
"sort_columns": [
{ "column": "created_at", "direction": "DESC" }
]
}WHERE dengan logika OR:
{
"page": 1,
"per_page": 10,
"where": {
"logic": "OR",
"conditions": [
{ "key": "supplier_name", "operator": "LIKE", "value": "%Maju%" },
{ "key": "supplier_code", "operator": "=", "value": "SUP-001" }
]
}
}Operator WHERE yang Didukung (Supported WHERE Operators)
| Operator | Keterangan | Contoh Value |
|---|---|---|
= | Sama dengan | "Jakarta" |
!= | Tidak sama dengan | "deleted" |
> | Lebih besar dari | 100 |
< | Lebih kecil dari | 50000 |
>= | Lebih besar atau sama dengan | 50000000 |
<= | Lebih kecil atau sama dengan | 1000 |
LIKE | Pencarian partial (wildcard %) | "%motor%" |
NOT LIKE | Tidak mengandung | "%test%" |
BETWEEN | Dalam rentang (array 2 elemen) | ["2026-01-01", "2026-12-31"] |
IN | Termasuk dalam daftar (array) | ["Jakarta", "Surabaya"] |
IS NULL | Bernilai null | (tidak perlu value) |
IS NOT NULL | Tidak bernilai null | (tidak perlu value) |
Format Response (Response Format)
Mode Paginasi (Pagination Mode)
HTTP 200 OK
{
"success": true,
"data": [
{
"supplier_id": "550e8400-e29b-41d4-a716-446655440000",
"supplier_code": "SUP-001",
"supplier_name": "PT Maju Jaya",
"email": "contact@majujaya.com",
"phone": "021-5551234",
"city": "Jakarta",
"is_active": true,
"created_at": "2026-04-16T10:30:00.000Z",
"created_by": "Input from API"
}
],
"count": 5,
"pagination": {
"current_page": 1,
"per_page": 10,
"total_records": 5,
"total_pages": 1,
"has_next": false,
"has_previous": false
},
"timestamp": "2026-04-16T10:30:00.000Z"
}Properti pagination hanya ada di mode paginasi dan berisi metadata berikut:
| Properti | Tipe | Keterangan |
|---|---|---|
current_page | number | Halaman yang sedang ditampilkan |
per_page | number | Jumlah record per halaman |
total_records | number | Total record yang cocok dengan filter |
total_pages | number | Total halaman yang tersedia |
has_next | boolean | Terdapat halaman berikutnya |
has_previous | boolean | Terdapat halaman sebelumnya |
Mode Non-Paginasi (Non-Pagination Mode)
HTTP 200 OK
{
"success": true,
"data": [
{
"supplier_id": "550e8400-e29b-41d4-a716-446655440000",
"supplier_code": "SUP-001",
"supplier_name": "PT Maju Jaya"
},
{
"supplier_id": "661f9511-f30c-52e5-b827-557766551111",
"supplier_code": "SUP-002",
"supplier_name": "CV Berkah Sentosa"
}
],
"count": 2,
"timestamp": "2026-04-16T10:30:00.000Z"
}Mode non-paginasi tidak menyertakan properti pagination. Properti count menunjukkan jumlah record yang dikembalikan.
Response Error (Error Responses)
400 — Payload kosong:
{
"success": false,
"error": "Invalid payload",
"message": "Payload cannot be empty",
"timestamp": "2026-04-16T10:30:00.000Z"
}400 — Parameter tidak valid:
{
"success": false,
"error": "Invalid parameter",
"message": "per_page must be between 1 and 100",
"timestamp": "2026-04-16T10:30:00.000Z"
}400 — Format WHERE tidak valid:
{
"success": false,
"error": "Invalid payload",
"message": "Invalid WHERE format. Expected object with 'conditions' array and 'logic' (AND/OR)",
"timestamp": "2026-04-16T10:30:00.000Z"
}400 — Kolom select tidak valid:
{
"success": false,
"error": "Invalid field",
"message": "Field 'unknown_field' is not a valid column",
"timestamp": "2026-04-16T10:30:00.000Z"
}500 — Internal server error:
{
"success": false,
"error": "Internal server error",
"message": "An unexpected error occurred",
"timestamp": "2026-04-16T10:30:00.000Z"
}Resolusi Sumber Data (Data Source Resolution)
Endpoint /read menggunakan prioritas resolusi sumber data berikut:
| Prioritas | Sumber | Konfigurasi Payload |
|---|---|---|
| 1 (tertinggi) | Database VIEW | "viewName": "vw_supplier_detail" |
| 2 | Virtual view | "viewQuery": "SELECT ... JOIN ..." |
| 3 (fallback) | Tabel langsung | "tableName": "supplier" |
Sistem memeriksa konfigurasi payload secara berurutan. Jika viewName dikonfigurasi, query akan dijalankan terhadap database VIEW tersebut. Jika tidak ada viewName tetapi ada viewQuery, query virtual view yang akan digunakan. Jika keduanya tidak ada, query dijalankan langsung terhadap tabel yang didefinisikan di tableName.
Default Scope
Jika defaultScope dikonfigurasi di payload, endpoint /read akan menerapkan kondisi WHERE tambahan secara otomatis pada setiap request. Default scope berguna untuk menerapkan filter global seperti is_active = true atau deleted_at IS NULL tanpa perlu mengirimkannya di setiap request.
Default scope diterapkan secara implisit dan digabungkan dengan kondisi WHERE dari request body menggunakan logika AND. Kondisi WHERE dari request tidak dapat menimpa atau membatalkan default scope.
Perilaku Cache (Cache Behavior)
Endpoint /read menggunakan Redis cache dengan key format rf:{project}:{endpoint}:list:{hash}, di mana {hash} merupakan hash dari seluruh parameter request. Request yang identik akan dilayani dari cache hingga cache di-invalidasi oleh operasi write (/create, /update, /delete, /adjust).
Perbandingan dengan /datatables (Comparison with /datatables)
| Aspek | /read | /datatables |
|---|---|---|
| Sumber query | viewName → viewQuery → tableName | datatablesQuery |
| Mode operasi | Paginasi + non-paginasi | Paginasi saja |
| WHERE | Operator kompleks (AND/OR, LIKE, BETWEEN, IN, dll.) | Search text sederhana |
| Cache | Redis cache | Tidak ada cache |
| Default scope | Diterapkan jika dikonfigurasi | Tidak diterapkan |
| Format response | Standar RESTForge | Format DataTables.net (draw, recordsTotal, recordsFiltered) |
| Use case | API konsumsi, mobile app, reporting | DataTables.net di browser |
Langkah Selanjutnya (Next Steps)
- POST /first untuk mengambil detail satu record
- POST /datatables untuk integrasi dengan DataTables.net
- POST /aggregate untuk fungsi agregasi (COUNT, SUM, AVG)
- Kode Error untuk referensi lengkap HTTP status code