Problematika Adopsi HTTP QUERY (RFC 10008) pada Tooling OpenAPI
Spesifikasi HTTP QUERY (RFC 10008) menstandarkan method yang aman (safe) dan idempoten untuk membaca resource dengan membawa payload request body. Method ini memecahkan keterbatasan panjang URI dan kompleksitas URL-encoding pada method GET tanpa menyalahgunakan semantik method POST.
Masalah utama muncul pada ekosistem developer tooling. Spesifikasi OpenAPI v3.0 dan v3.1 mendefinisikan objek Path Item dengan daftar method tetap: get, put, post, delete, options, head, patch, dan trace. Default ruleset linter seperti Stoplight Spectral (spectral:oas) akan menandai penambahan properti query pada root path sebagai schema violation:
paths./search.query: Property `query` is not allowed. [oas3-schema]Sebagian tim menyiasatinya menggunakan POST dengan header kustom atau x-http-method: QUERY, namun pendekatan ini merusak kontrak dokumentasi standar. Solusi yang benar adalah memodifikasi pipeline linting agar mengenali method query sekaligus memvalidasi struktur payload dan integritas header.
Menyusun Ruleset Spectral Kustom
Untuk mendukung method query pada OpenAPI tanpa mematikan validasi esensial lainnya, buat ruleset khusus yang mengekstrak dan memvalidasi operasi tersebut. Simpan konfigurasi ini pada file .spectral.yaml.
extends: [spectral:oas]
rules:
# Matikan validasi strict schema bawaan untuk properti method yang belum final
oas3-schema:
severity: warn
# Wajibkan deklarasi requestBody untuk method QUERY
query-requires-request-body:
description: "Operasi HTTP QUERY harus mendefinisikan requestBody."
message: "Path {{path}} dengan method QUERY wajib menyertakan properti requestBody."
severity: error
given: "$.paths.*.query"
then:
field: requestBody
defined: true
# Validasi media type pada payload QUERY
query-content-type-json:
description: "Request body HTTP QUERY harus mendukung Content-Type application/json."
message: "Content-Type application/json tidak ditemukan pada {{path}}."
severity: error
given: "$.paths.*.query.requestBody.content"
then:
field: "application/json"
defined: true
# Pastikan skema payload terdefinisi dengan tipe object
query-body-schema-object:
description: "Schema JSON untuk payload QUERY harus bertipe object."
message: "Skema payload pada {{path}} harus memiliki tipe object."
severity: error
given: "$.paths.*.query.requestBody.content['application/json'].schema"
then:
field: type
enumeration:
- objectRuleset di atas memastikan setiap endpoint dengan method query tidak hanya lolos audit schema, melainkan juga tetap terikat pada kontrak data ketat: wajib menyediakan payload JSON berformat objek terstruktur.
Implementasi Dokumen OpenAPI untuk QUERY
Berikut adalah contoh pendefinisian endpoint pencarian katalog menggunakan method query dalam file openapi.yaml:
openapi: 3.1.0
info:
title: Catalog Query Service
version: 1.0.0
paths:
/items:
query:
summary: Pencarian item berbasis filter kompleks
operationId: queryItems
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- filters
properties:
filters:
type: object
properties:
category:
type: string
priceRange:
type: object
properties:
min:
type: number
max:
type: number
responses:
'200':
description: Berhasil mengambil data
content:
application/json:
schema:
type: array
items:
type: object
'422':
description: Payload query tidak validOtomasi Validasi di Pipeline CI (GitHub Actions)
Terapkan step linting pada pipeline pull request untuk mencegah developer mendistribusikan kontrak API yang tidak memenuhi standar RFC 10008.
Simpan workflow berikut di .github/workflows/lint-contract.yaml:
name: Contract Linting
on:
pull_request:
paths:
- 'openapi.yaml'
- '.spectral.yaml'
jobs:
spectral-lint:
name: Validate OpenAPI Specification
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install Spectral CLI
run: npm install -g @stoplight/spectral-cli
- name: Run Spectral Lint
run: |
spectral lint openapi.yaml --ruleset .spectral.yaml --fail-severity=error --display-only-failuresFlag --fail-severity=error memastikan proses build CI langsung berhenti ketika ditemukan pelanggaran pada kontrak QUERY, sementara warning non-kritis tidak mengganggu alur deployment.
DX: Mock Server Lokal dan Validasi Error Handling
Untuk keperluan pengujian lokal tanpa menunggu backend selesai diimplementasikan, jalankan mock server berbasis spek menggunakan Node.js atau Prism CLI:
npx @stoplight/prism-cli mock openapi.yaml -p 4010Lakukan verifikasi penolakan payload terhadap mock server menggunakan curl:
# Test 1: Request valid
curl -X QUERY http://127.0.0.1:4010/items \
-H "Content-Type: application/json" \
-d '{"filters": {"category": "hardware"}}'
# Test 2: Request tidak valid (missing required field: filters)
curl -X QUERY http://127.0.0.1:4010/items \
-H "Content-Type: application/json" \
-d '{"invalidKey": 123}'Jika kontrak divalidasi dengan benar, mock engine akan merespons request kedua dengan kode status 422 Unprocessable Content yang mencantumkan detail schema violation.
Checklist Pencegahan Breaking Changes
- Reverse Proxy Readiness: Pastikan NGINX, Cloudflare, atau AWS ALB di depan service tidak memblokir method
QUERYatau menghapus body request pada layer L7. - Fallback Semantics: Bila upstream proxy membatasi method kustom, tentukan apakah service menerima header alternatif
X-HTTP-Method-Override: QUERY. - Idempotency Validation: Hindari mutasi status database di sisi backend saat memproses method ini. Kontrak RFC 10008 menuntut operasi bersifat safe.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!