IETF baru saja merilis RFC 10008 yang mendefinisikan HTTP QUERY method. Spesifikasi ini mengisi celah yang selama ini menjadi masalah klasik di dunia web development: bagaimana melakukan query kompleks yang aman dan idempotent ketika parameter terlalu panjang untuk dimuat dalam URL GET.
Artikel ini akan membahas konsep dasar QUERY method, kapan menggunakannya dibandingkan GET atau POST, dan bagaimana mengimplementasikannya di Express.js dengan contoh kode yang bisa langsung dicoba.
Sebelum QUERY method, developer memiliki dua pilihan utama untuk mengambil data dari server:
GET: Aman dan idempotent, tapi semua parameter harus masuk ke query string URL. Ada batas praktis sekitar 2000-8000 karakter tergantung browser dan server. Untuk query kompleks dengan banyak filter, nested conditions, atau large payloads, GET sering kali tidak memadai.
POST: Bisa membawa body request sebesar apapun, tapi tidak secara semantik bersifat idempotent. Proxy dan middleware sering kali tidak meng-cache response POST. Lebih parah lagi, retry otomatis bisa menyebabkan side effects jika endpoint tidak didesain dengan hati-hati.
QUERY method hadir sebagai solusi tengah: seperti POST, ia mengirimkan query parameter melalui request body. Seperti GET, ia secara eksplisit didefinisikan sebagai safe dan idempotent. Ini berarti cache bisa bekerja, retry otomatis aman, dan semantik HTTP tetap terjaga.
RFC 10008 menyajikan tabel perbandingan yang jelas antara GET, QUERY, dan POST:
| Properti | GET | QUERY | POST |
|---|---|---|---|
| Safe | ya | ya | potensial tidak |
| Idempotent | ya | ya | potensial tidak |
| URI untuk query | ya (by definition) | opsional (Location header) | tidak |
| Cacheable | ya | ya | terbatas |
| Body content | tidak didefinisikan | diharapkan | diharapkan |
Keunggulan utama QUERY adalah kemampuannya membawa query content dalam body sambil tetap mempertahankan karakteristik safe dan idempotent dari GET.
Buat project baru dan instal dependencies:
mkdir query-method-demo
cd query-method-demo
npm init -y
npm install expressBuat file server.js dengan struktur dasar Express:
const express = require("express");
const app = express();
const PORT = 3000;
app.use(express.json());
app.listen(PORT, () => {
console.log("Server berjalan di http://localhost:" + PORT);
});Express secara default tidak mengenali method QUERY, jadi kita perlu menambahkan custom method handler.
Express hanya secara native support method standar HTTP. Untuk QUERY, kita perlu meng-override routing layer sedikit. Gunakan middleware berikut sebelum definisi route:
app.use((req, res, next) => {
if (req.method === "QUERY") {
req.method = "GET";
req.isQueryMethod = true;
}
next();
});Catatan: pendekatan di atas adalah workaround praktis. Di production dengan load balancer atau reverse proxy, kamu mungkin perlu konfigurasi tambahan agar method QUERY tidak di-block.
Buat endpoint untuk melakukan pencarian produk dengan filter kompleks. Bayangkan skenario e-commerce dengan filter dinamis: rentang harga, multiple kategori, rating minimum, dan sorting.
const products = [
{ id: 1, name: "Laptop Gaming", category: "elektronik", price: 15000000, rating: 4.5 },
{ id: 2, name: "Meja Kerja", category: "furniture", price: 2500000, rating: 4.2 },
{ id: 3, name: "Monitor 4K", category: "elektronik", price: 8000000, rating: 4.7 },
];
app.get("/api/products/search", (req, res) => {
const queryContent = req.isQueryMethod ? req.body : req.query;
let results = products;
if (queryContent.categories) {
results = results.filter(p => queryContent.categories.includes(p.category));
}
if (queryContent.minPrice) {
results = results.filter(p => p.price >= queryContent.minPrice);
}
if (queryContent.maxPrice) {
results = results.filter(p => p.price <= queryContent.maxPrice);
}
if (queryContent.minRating) {
results = results.filter(p => p.rating >= queryContent.minRating);
}
if (queryContent.sortBy) {
const [field, order] = queryContent.sortBy.split(":");
results.sort((a, b) => {
return order === "desc" ? b[field] - a[field] : a[field] - b[field];
});
}
res.json({
count: results.length,
queryMethod: req.isQueryMethod ? "QUERY" : "GET",
data: results
});
});Perhatikan bahwa handler ini bisa melayani baik GET maupun QUERY. Hal ini memudahkan migrasi bertahap.
Ulangi request yang sama dengan GET dan QUERY untuk melihat perbedaannya.
Request menggunakan GET (terbatas query string):
curl "http://localhost:3000/api/products/search?categories=elektronik&minPrice=5000000"Request menggunakan QUERY (body JSON):
curl -X QUERY http://localhost:3000/api/products/search \
-H "Content-Type: application/json" \
-d '{
"categories": ["elektronik", "furniture"],
"minPrice": 1000000,
"maxPrice": 20000000,
"minRating": 4.0,
"sortBy": "price:desc"
}'Response dari QUERY request akan menunjukkan bahwa method yang digunakan adalah QUERY, dan filter yang diterapkan jauh lebih kompleks dibandingkan yang bisa dicapai dengan query string sederhana.
Salah satu fitur menarik dari RFC 10008 adalah kemampuan server memberikan URI yang mengidentifikasi query itu sendiri melalui header Location. Ini memungkinkan client menyimpan atau membagikan query kompleks sebagai URL tunggal.
if (req.isQueryMethod) {
const queryId = Buffer.from(JSON.stringify(queryContent)).toString("base64url");
res.location(`/api/products/search/queries/${queryId}`);
}Dengan mekanisme ini, query yang kompleks bisa di-share sebagai link, dan server bisa mengimplementasikan caching layer yang efisien.
Sebelum mengadopsi QUERY method di production, perhatikan beberapa hal:
Infrastructure support: Beberapa load balancer, WAF, atau CDN mungkin belum mengenali method QUERY. Uji di staging environment terlebih dahulu.
Client compatibility: Browser fetch API dan library HTTP modern umumnya mendukung custom method, tapi test dengan stack teknologi yang kamu gunakan.
Cache invalidation: Karena QUERY bisa di-cache seperti GET, pastikan strategi cache invalidation sudah matang. Gunakan ETag atau versioning query jika diperlukan.
Content-Type negotiation: RFC mensyaratkan server mengembalikan 400 Bad Request jika Content-Type tidak sesuai atau tidak ada. Implementasikan validasi ini untuk compliance penuh.
RFC 10008 membuka kemungkinan baru untuk desain API yang lebih bersih dan semantik. QUERY method bukan pengganti GET untuk query sederhana, tapi adalah solusi elegan untuk skenario kompleks di mana body request diperlukan.
Implementasi di Node.js relatif mudah dengan sedikit workaround di Express. Seiring dengan adopsi infrastruktur, QUERY method berpotensi menjadi standar baru untuk search API, reporting endpoints, dan GraphQL-like queries over HTTP.
Dokumen resmi RFC tersedia di rfc-editor.org/info/rfc10008. Pelajari spesifikasi lengkapnya sebelum menerapkan di sistem production.
Dapatkan feedback, users, dan eksposur dari komunitas kreator, developer, dan entrepreneur digital Indonesia.
Submit Produk → Pelajari Dulu