📋
← Kembali ke Panduan

Menggunakan JSON di REST API: Praktik Terbaik

· Tag: json, rest-api, api-design, json-best-practices, pagination, web-development

JSON di REST API

JSON dan REST API adalah pasangan yang sempurna. Sintaks ringan JSON, dukungan array native, dan dukungan bahasa universal menjadikannya format default untuk API web modern. Tetapi hanya menggunakan JSON di API Anda tidak cukup -- mengikuti konvensi dan praktik terbaik yang mapan memastikan API Anda konsisten, intuitif, dan mudah diintegrasikan.

Format Request dan Response

Struktur Envelope yang Konsisten

Adopsi envelope JSON yang konsisten untuk semua respons API. Ini membuat pemrosesan sisi klien dapat diprediksi dan menyederhanakan penanganan kesalahan.

{
  "status": "success",
  "data": {
    "user": {
      "id": 123,
      "name": "Alice",
      "email": "alice@example.com"
    }
  },
  "meta": {
    "requestId": "req-a1b2c3d4",
    "timestamp": "2026-07-19T10:30:00Z"
  }
}

Snake Case vs Camel Case

Pilih satu konvensi penamaan dan patuhi di seluruh API Anda:

  • Camel Case (createdAt, firstName): Umum di ekosistem JavaScript/TypeScript
  • Snake Case (created_at, first_name): Umum di ekosistem Python, Ruby, dan PHP

Apa pun yang Anda pilih, dokumentasikan dengan jelas dan pertimbangkan menggunakan lapisan transformasi jika bahasa backend Anda menggunakan konvensi yang berbeda.

Kode Status HTTP dengan JSON

Kode status HTTP yang tepat melengkapi respons JSON Anda. Gunakan secara konsisten:

| Kode Status | Arti | Kapan Digunakan | |-------------|---------|-------------| | 200 OK | Sukses | GET, PUT, PATCH sukses | | 201 Created | Sumber daya dibuat | POST sukses | | 204 No Content | Penghapusan sukses | DELETE sukses (tanpa body JSON) | | 400 Bad Request | Sintaks JSON tidak valid | Body permintaan salah format | | 401 Unauthorized | Autentikasi diperlukan | Token hilang atau tidak valid | | 403 Forbidden | Izin tidak mencukupi | Auth valid tetapi tidak diizinkan | | 404 Not Found | Sumber daya tidak ada | ID atau jalur tidak valid | | 422 Unprocessable Entity | Kegagalan validasi | Kesalahan semantik dalam JSON valid | | 429 Too Many Requests | Batas rate tercapai | Klien melebihi batas | | 500 Internal Server Error | Kegagalan sisi server | Kesalahan tak terduga |

Format Respons Kesalahan Standar

{
  "status": "error",
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "The request body contains invalid fields",
    "details": [
      {
        "field": "email",
        "message": "Must be a valid email address",
        "code": "INVALID_FORMAT"
      },
      {
        "field": "age",
        "message": "Must be a positive integer",
        "code": "OUT_OF_RANGE"
      }
    ]
  }
}

Sumber Daya Bersarang

Merepresentasikan Relasi

REST API sering kali perlu merepresentasikan sumber daya yang terkait. Berikut adalah pola umum:

Embedded (eager loading):

{
  "order": {
    "id": 5001,
    "total": 29.99,
    "customer": {
      "id": 123,
      "name": "Alice",
      "email": "alice@example.com"
    },
    "items": [
      {
        "productId": 42,
        "name": "Widget",
        "quantity": 2,
        "price": 14.99
      }
    ]
  }
}

Referenced (lazy loading) -- gunakan ID dan sediakan endpoint terpisah:

{
  "order": {
    "id": 5001,
    "total": 29.99,
    "customerId": 123,
    "itemIds": [101, 102]
  }
}

Aturan praktis: Sematkan data terkait yang selalu dibutuhkan bersama. Referensikan data yang diambil secara kondisional atau pada waktu yang berbeda.

Pola Paginasi

Saat mengembalikan daftar sumber daya, paginasi sangat penting. Gunakan format paginasi yang konsisten:

Paginasi Berbasis Offset

{
  "status": "success",
  "data": [
    { "id": 1, "name": "User 1" },
    { "id": 2, "name": "User 2" }
  ],
  "pagination": {
    "page": 1,
    "perPage": 20,
    "totalItems": 156,
    "totalPages": 8,
    "links": {
      "first": "/api/users?page=1&perPage=20",
      "prev": null,
      "next": "/api/users?page=2&perPage=20",
      "last": "/api/users?page=8&perPage=20"
    }
  }
}

Paginasi Berbasis Kursor (Direkomendasikan untuk Dataset Besar)

{
  "status": "success",
  "data": [
    { "id": 100, "name": "User 100" },
    { "id": 101, "name": "User 101" }
  ],
  "pagination": {
    "nextCursor": "eyJpZCI6MTAxfQ==",
    "hasMore": true
  }
}

Paginasi berbasis kursor lebih andal untuk data real-time di mana record baru dapat menggeser batas halaman.

JSON dalam Permintaan API

Body Permintaan POST / PUT

Terima JSON dengan header Content-Type: application/json:

{
  "title": "New Blog Post",
  "content": "This is the content...",
  "tags": ["json", "rest-api"],
  "published": false
}

Pembaruan Parsial dengan PATCH

Gunakan PATCH untuk pembaruan parsial. Terima hanya field yang harus berubah:

// PATCH /api/users/123
{
  "email": "newemail@example.com"
}

Filtering, Sorting, dan Searching

Gunakan parameter kueri untuk manipulasi data, menjaga body JSON tetap bersih:

GET /api/users?filter[role]=admin&sort=-createdAt&search=alice
{
  "status": "success",
  "data": [ /* filtered, sorted results */ ]
}

Rate Limiting

Sertakan informasi rate limit di header respons dan secara opsional di body JSON:

{
  "status": "error",
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Too many requests. Please try again later."
  },
  "meta": {
    "rateLimit": {
      "limit": 100,
      "remaining": 0,
      "resetAt": "2026-07-19T11:00:00Z"
    }
  }
}

Checklist Praktik Terbaik JSON

  • [ ] Gunakan penamaan kunci yang konsisten (camelCase atau snake_case di seluruh)
  • [ ] Kembalikan kode status HTTP yang sesuai dengan setiap respons
  • [ ] Sertakan format kesalahan yang konsisten dengan kode kesalahan yang dapat dibaca mesin
  • [ ] Paginasi endpoint daftar dengan objek paginasi terstandarisasi
  • [ ] Gunakan JSON Schema untuk mendokumentasikan dan memvalidasi struktur request/response
  • [ ] Setel Content-Type: application/json pada semua endpoint JSON
  • [ ] Kompres respons JSON dengan gzip atau brotli di production
  • [ ] Terapkan batas ukuran payload maksimum (misalnya, default 1MB)
  • [ ] Gunakan HTTPS untuk mengenkripsi data JSON dalam transit
  • [ ] Struktur detail kesalahan untuk membantu klien debug tanpa mengekspos internal

Memvalidasi JSON API Anda

Jalankan respons API Anda melalui validator JSON untuk menangkap kesalahan formatting sebelum mencapai klien. Respons JSON yang konsisten dan valid membuat API Anda andal dan ramah pengembang. Gunakan alat JSON Formatter & Validator kami untuk menguji payload Anda selama pengembangan.