Strategi Versioning API Terbaik: URL, Header, atau Negosiasi Konten?

Ashley Innocent

Ashley Innocent

13 March 2026

Strategi Versioning API Terbaik: URL, Header, atau Negosiasi Konten?

TL;DR

Pembuatan versi URL (/v1/pets) adalah strategi pembuatan versi API yang paling praktis untuk sebagian besar tim. Ini terlihat, dapat di-cache, dan mudah diuji. Pembuatan versi header dan negosiasi konten lebih "murni" REST tetapi menambah kerumitan. Modern PetstoreAPI menggunakan pembuatan versi URL dengan pembuatan versi semantik dan kebijakan penghentian yang jelas.

Pendahuluan

API Anda membutuhkan perubahan yang merusak. Anda mengubah format respons untuk /pets dari array kosong menjadi objek terbungkus dengan metadata paginasi. Klien yang ada akan rusak. Apa yang Anda lakukan?

Anda memerlukan pembuatan versi API. Tapi strategi mana? Pembuatan versi URL (/v1/pets vs /v2/pets)? Pembuatan versi header (Accept: application/vnd.petstore.v1+json)? Negosiasi konten? Setiap pendekatan memiliki pendukung yang antusias dan opini yang kuat.

Jawabannya: pembuatan versi URL menang untuk sebagian besar tim. Ini pragmatis, terlihat, dan berfungsi dengan semua peralatan HTTP. Pembuatan versi header dan negosiasi konten secara teoritis lebih bersih tetapi menambah kerumitan yang tidak dibutuhkan sebagian besar tim.

Modern PetstoreAPI menggunakan pembuatan versi URL dengan pembuatan versi semantik dan kebijakan penghentian yang jelas. Versi saat ini adalah v1, dengan v2 direncanakan untuk perubahan yang merusak di masa mendatang.

💡
Jika Anda membangun atau menguji API REST, Apidog membantu Anda menguji berbagai versi API, memvalidasi perilaku spesifik versi, dan memastikan kompatibilitas mundur. Anda dapat mempertahankan spesifikasi terpisah untuk setiap versi dan menjalankan pengujian terhadap semua versi secara bersamaan.
tombol

Dalam panduan ini, Anda akan mempelajari tiga strategi pembuatan versi utama, pro dan kontranya, serta cara menerapkan pembuatan versi dengan benar menggunakan Modern PetstoreAPI sebagai referensi.

Mengapa API Membutuhkan Pembuatan Versi

API berkembang. Anda menambahkan fitur, memperbaiki bug, dan meningkatkan desain. Terkadang perubahan ini merusak klien yang sudah ada.

Perubahan yang Merusak

Perubahan yang merusak klien yang sudah ada:

1. Menghapus field:

// v1
{"id": "123", "name": "Fluffy", "age": 3}

// v2 (merusak: age dihapus)
{"id": "123", "name": "Fluffy"}

2. Mengubah tipe field:

// v1
{"price": "19.99"}

// v2 (merusak: string menjadi number)
{"price": 19.99}

3. Mengubah struktur respons:

// v1 (array kosong)
[{"id": "123"}]

// v2 (merusak: objek terbungkus)
{"data": [{"id": "123"}], "pagination": {...}}

4. Mengubah struktur URL:

// v1
GET /pet/123

// v2 (merusak: jamak)
GET /pets/123

5. Mengubah otentikasi:

// v1: API key di kueri
GET /pets?api_key=xxx

// v2 (merusak: token Bearer)
GET /pets
Authorization: Bearer xxx

Perubahan yang Tidak Merusak

Perubahan yang tidak merusak klien:

Keputusan Pembuatan Versi

Saat Anda membutuhkan perubahan yang merusak, Anda memiliki dua pilihan:

1. Memaksa semua klien untuk meng-upgrade - Sederhana tetapi merusak integrasi yang ada

2. Mendukung beberapa versi - Lebih banyak pekerjaan tetapi mempertahankan kompatibilitas mundur

Sebagian besar API publik memilih opsi 2. Pembuatan versi memungkinkan Anda mengembangkan API sambil memberi waktu kepada klien untuk bermigrasi.

Pembuatan Versi URL

Pembuatan versi URL menempatkan nomor versi di jalur URL.

Cara Kerjanya

GET /v1/pets
GET /v2/pets

Versi adalah bagian dari pengidentifikasi sumber daya. Versi yang berbeda adalah sumber daya yang berbeda.

Kelebihan

1. Terlihat dan eksplisit

Versi ada di URL. Anda dapat melihatnya di log, riwayat peramban, dan dokumentasi. Tidak ada header tersembunyi yang perlu diingat.

2. Mudah diuji

curl https://petstoreapi.com/v1/pets
curl https://petstoreapi.com/v2/pets

Anda dapat menguji kedua versi dengan permintaan HTTP sederhana.

3. Berfungsi dengan semua peralatan HTTP

Peramban, cache, proksi, dan penyeimbang beban melihat URL yang berbeda. Mereka dapat merutekan, menyimpan, dan mencatat setiap versi secara independen.

4. Sederhana untuk klien

Klien hanya perlu mengubah URL. Tidak ada header kustom atau logika negosiasi konten.

5. Mudah untuk dihentikan

Anda dapat menghapus endpoint /v1 tanpa memengaruhi /v2.

Kekurangan

1. Bukan REST "murni"

Penganut REST yang murni berpendapat bahwa /v1/pets/123 dan /v2/pets/123 adalah sumber daya yang sama, jadi mereka harus memiliki URL yang sama. Versi harus berada di header atau negosiasi konten.

2. Polusi URL

API Anda memiliki beberapa ruang URL: /v1/*, /v2/*, dll.

3. Lebih sulit untuk membuat versi sumber daya individual

Jika Anda ingin membuat versi hanya satu endpoint, Anda perlu membuat versi seluruh API atau menciptakan inkonsistensi.

Implementasi

Versi utama di URL:

/v1/pets
/v2/pets

Jangan sertakan versi minor:

❌ /v1.2/pets  (terlalu granular)
✅ /v1/pets    (hanya versi utama)

Gunakan pembuatan versi semantik secara internal:

Modern PetstoreAPI menggunakan pembuatan versi URL dengan /v1 sebagai versi saat ini.

Pembuatan Versi Header

Pembuatan versi header menempatkan versi di header HTTP kustom.

Cara Kerjanya

GET /pets
API-Version: 1

GET /pets
API-Version: 2

URL tetap sama. Header menentukan versi.

Kelebihan

1. URL yang bersih

/pets sama untuk semua versi. Tanpa awalan /v1 atau /v2.

2. Lebih "RESTful"

Pengidentifikasi sumber daya (/pets/123) tidak berubah. Representasi berubah berdasarkan header.

3. Pembuatan versi yang terperinci

Anda dapat membuat versi sumber daya individual:

GET /pets
API-Version: 2

GET /orders
API-Version: 1

Kekurangan

1. Tidak terlihat

Versi tidak ada di URL. Anda tidak dapat melihatnya di log atau riwayat peramban tanpa memeriksa header.

2. Lebih sulit diuji

curl -H "API-Version: 1" https://petstoreapi.com/pets
curl -H "API-Version: 2" https://petstoreapi.com/pets

Anda harus ingat untuk menyertakan header.

3. Kompleksitas caching

Cache harus mempertimbangkan header API-Version. Anda memerlukan Vary: API-Version di respons.

4. Kompleksitas klien

Klien memerlukan logika header kustom. Tidak semua klien HTTP membuatnya mudah.

5. Ambiguitas versi default

Apa yang terjadi jika klien tidak mengirimkan header? Anda memerlukan default, yang menciptakan perilaku implisit.

Implementasi

Header kustom:

API-Version: 1

Atau gunakan header Accept:

Accept: application/vnd.petstore.v1+json

Sertakan header Vary:

Vary: API-Version

Ini memberitahu cache untuk mempertimbangkan header saat melakukan caching.

Negosiasi Konten

Negosiasi konten menggunakan header Accept dengan tipe media kustom.

Cara Kerjanya

GET /pets
Accept: application/vnd.petstore.v1+json

GET /pets
Accept: application/vnd.petstore.v2+json

Versi adalah bagian dari tipe media.

Kelebihan

1. Paling "RESTful"

Beginilah cara REST dirancang. Representasi yang berbeda dari sumber daya yang sama.

2. Mengikuti standar HTTP

Menggunakan negosiasi konten HTTP standar.

3. Mendukung banyak format

Anda dapat membuat versi dan memformat secara bersamaan:

Accept: application/vnd.petstore.v1+json
Accept: application/vnd.petstore.v1+xml

Kekurangan

1. Kompleks

Klien harus memahami tipe media dan negosiasi konten.

2. Lebih sulit diuji

curl -H "Accept: application/vnd.petstore.v1+json" https://petstoreapi.com/pets

3. Dukungan peralatan yang buruk

Banyak klien dan peralatan HTTP tidak menangani tipe media kustom dengan baik.

4. Kompleksitas caching

Cache harus mempertimbangkan header Accept. Anda memerlukan Vary: Accept.

5. Berlebihan untuk sebagian besar API

Sebagian besar API tidak memerlukan tingkat kecanggihan ini.

Implementasi

Tipe media spesifik vendor:

Accept: application/vnd.petstore.v1+json

Respons:

Content-Type: application/vnd.petstore.v1+json
Vary: Accept

Bagaimana Modern PetstoreAPI Menerapkan Pembuatan Versi

Modern PetstoreAPI menggunakan pembuatan versi URL dengan kebijakan yang jelas.

Versi Saat Ini: v1

https://petstoreapi.com/v1/pets
https://petstoreapi.com/v1/orders
https://petstoreapi.com/v1/users

Semua endpoint berada di bawah /v1.

Header Respons Versi

Setiap respons menyertakan versi API:

X-API-Version: 1.2.0

Ini menunjukkan versi persisnya (major.minor.patch) meskipun URL hanya menunjukkan versi utama.

Peringatan Penghentian

Ketika suatu versi dihentikan, respons menyertakan:

Deprecation: true
Sunset: Sat, 31 Dec 2026 23:59:59 GMT
Link: <https://docs.petstoreapi.com/migration/v1-to-v2>; rel="deprecation"

Penemuan Versi

Endpoint root mencantumkan versi yang tersedia:

GET https://petstoreapi.com/

{
  "versions": [
    {
      "version": "v1",
      "status": "current",
      "docsUrl": "https://docs.petstoreapi.com/v1"
    }
  ]
}

Pembuatan Versi Semantik

Modern PetstoreAPI mengikuti pembuatan versi semantik secara internal:

Hanya versi mayor yang muncul di URL.

Menguji Versi API dengan Apidog

Apidog membantu Anda menguji berbagai versi API.

Mengimpor Berbagai Versi

Impor spesifikasi OpenAPI untuk setiap versi:

petstore-v1.yaml → Lingkungan: v1
petstore-v2.yaml → Lingkungan: v2

Menjalankan Pengujian Terhadap Semua Versi

Buat rangkaian pengujian yang berjalan terhadap kedua versi:

// Uji v1
pm.environment.set("baseUrl", "https://petstoreapi.com/v1");
pm.sendRequest(pm.environment.get("baseUrl") + "/pets");

// Uji v2
pm.environment.set("baseUrl", "https://petstoreapi.com/v2");
pm.sendRequest(pm.environment.get("baseUrl") + "/pets");

Memvalidasi Perilaku Spesifik Versi

Uji bahwa v1 dan v2 berperilaku berbeda:

// v1 mengembalikan array kosong
pm.test("v1 mengembalikan array", function() {
    pm.expect(pm.response.json()).to.be.an('array');
});

// v2 mengembalikan objek terbungkus
pm.test("v2 mengembalikan objek terbungkus", function() {
    pm.expect(pm.response.json()).to.have.property('data');
    pm.expect(pm.response.json()).to.have.property('pagination');
});

Memeriksa Header Penghentian

Uji bahwa versi yang dihentikan menyertakan header yang tepat:

pm.test("Versi yang dihentikan menyertakan header", function() {
    pm.response.to.have.header("Deprecation");
    pm.response.to.have.header("Sunset");
});

Strategi Penghentian Versi

Cara menghentikan versi lama tanpa merusak klien.

1. Umumkan Penghentian Lebih Awal

Beri klien setidaknya pemberitahuan 6-12 bulan:

Deprecation: true
Sunset: Sat, 31 Dec 2026 23:59:59 GMT

2. Sediakan Panduan Migrasi

Dokumentasikan semua perubahan yang merusak dan cara bermigrasi:

Link: <https://docs.petstoreapi.com/migration/v1-to-v2>; rel="deprecation"

3. Pantau Penggunaan

Lacak klien mana yang masih menggunakan versi yang dihentikan:

X-API-Version: 1.2.0
X-Client-ID: abc123

Hubungi klien secara langsung jika diperlukan.

4. Penonaktifan Bertahap

Jangan segera menghapus versi:

  1. Bulan 1-6: Umumkan penghentian
  2. Bulan 7-9: Tambahkan header penghentian
  3. Bulan 10-11: Kurangi batas kecepatan untuk versi yang dihentikan
  4. Bulan 12: Hapus versi yang dihentikan

5. Pertahankan Dokumentasi

Bahkan setelah dihapus, simpan dokumentasi untuk versi lama. Klien mungkin perlu merujuknya.

Kesimpulan

Pembuatan versi URL adalah strategi pembuatan versi API yang paling praktis untuk sebagian besar tim. Ini terlihat, mudah diuji, dan berfungsi dengan semua peralatan HTTP. Pembuatan versi header dan negosiasi konten lebih "murni" REST tetapi menambah kerumitan.

Modern PetstoreAPI menggunakan pembuatan versi URL dengan /v1 sebagai versi saat ini, pembuatan versi semantik secara internal, dan kebijakan penghentian yang jelas. Pendekatan ini menyeimbangkan pragmatisme dengan desain API yang baik.

Gunakan Apidog untuk menguji berbagai versi API, memvalidasi perilaku spesifik versi, dan memastikan migrasi yang lancar antar versi.

tombol

FAQ

Haruskah saya menggunakan pembuatan versi URL atau pembuatan versi header?

Gunakan pembuatan versi URL kecuali Anda memiliki alasan khusus untuk tidak melakukannya. Ini lebih sederhana, lebih terlihat, dan lebih mudah diuji. Pembuatan versi header lebih "RESTful" tetapi menambah kerumitan yang tidak dibutuhkan sebagian besar tim.

Berapa banyak versi yang harus saya dukung secara bersamaan?

Dukung maksimal 2 versi: saat ini dan sebelumnya. Mendukung lebih banyak menciptakan beban pemeliharaan. Beri klien 6-12 bulan untuk bermigrasi, lalu hapus versi lama.

Haruskah saya membuat versi dari v0 atau v1?

Mulai dengan v1. v0 menyiratkan ketidakstabilan. Jika API Anda belum cukup stabil untuk v1, jangan rilis secara publik dulu.

Apakah saya perlu membuat versi setiap endpoint?

Tidak. Hanya buat versi ketika Anda membuat perubahan yang merusak. Jika Anda menambahkan endpoint baru tanpa mengubah yang sudah ada, Anda tidak memerlukan versi baru.

Bagaimana dengan versi minor di URL?

Jangan sertakan versi minor di URL. Gunakan /v1, bukan /v1.2. Versi minor kompatibel mundur, sehingga klien tidak perlu mengubah URL.

Bagaimana saya menangani bug spesifik versi?

Perbaiki bug di semua versi yang didukung. Jika bug hanya ada di v1, perbaiki di v1. Jangan memaksa klien untuk meng-upgrade ke v2 untuk perbaikan bug.

Haruskah saya menggunakan pembuatan versi semantik?

Ya, secara internal. Lacak versi major.minor.patch, tetapi hanya ekspos versi mayor di URL. Ini memberi Anda fleksibilitas untuk perubahan yang tidak merusak.

Bagaimana jika saya hanya perlu membuat versi satu endpoint?

Dengan pembuatan versi URL, Anda perlu membuat versi seluruh API atau menciptakan inkonsistensi. Ini adalah kompromi. Sebagian besar tim menerima pembuatan versi seluruh API demi kesederhanaan.

Mengembangkan API dengan Apidog

Apidog adalah alat pengembangan API yang membantu Anda mengembangkan API dengan lebih mudah dan efisien.