Pertanyaan Praktik terbaik untuk versi API? [Tutup]


Apakah ada praktik yang diketahui atau praktik terbaik untuk versi API REST API layanan web?

Saya telah memperhatikan hal itu AWS melakukan pembuatan versi oleh URL titik akhir. Apakah ini satu-satunya cara atau apakah ada cara lain untuk mencapai tujuan yang sama? Jika ada banyak cara, apa manfaat dari masing-masing cara?


878
2017-12-23 15:32


asal


Jawaban:


Ini pertanyaan yang bagus dan rumit. Topik tentang Desain URI adalah pada waktu bersamaan bagian paling menonjol dari REST API dan, oleh karena itu, berpotensi komitmen jangka panjang terhadap pengguna API itu.

Sejak evolusi aplikasi dan, pada tingkat yang lebih rendah, API-nya adalah fakta kehidupan dan bahkan mirip dengan evolusi produk yang tampaknya rumit seperti bahasa pemrograman, Desain URI seharusnya lebih sedikit kendala alami dan itu harus dipertahankan dari waktu ke waktu. Semakin panjang umur aplikasi dan API, semakin besar komitmen untuk pengguna aplikasi dan API.

Di sisi lain, fakta lain dari kehidupan adalah sulit untuk memperkirakan semua sumber daya dan aspek mereka yang akan dikonsumsi melalui API. Untungnya, tidak perlu merancang seluruh API yang akan digunakan sampai Wahyu. Cukup untuk mendefinisikan semua titik akhir sumber daya dan skema pengalamatan dari setiap sumber daya dan sumber daya contoh.

Seiring waktu Anda mungkin perlu menambahkan sumber daya baru dan atribut baru untuk setiap sumber daya tertentu, tetapi metode yang diikuti pengguna API untuk mengakses sumber daya tertentu tidak boleh berubah setelah skema pengalamatan sumber daya menjadi publik dan karena itu bersifat final.

Metode ini berlaku untuk semantik kata kerja HTTP (misalnya PUT harus selalu memperbarui / mengganti) dan kode status HTTP yang didukung dalam versi API sebelumnya (mereka harus terus bekerja sehingga klien API yang telah bekerja tanpa campur tangan manusia harus dapat terus bekerja seperti itu).

Selanjutnya, sejak penyematan versi API ke URI akan mengganggu konsep hypermedia sebagai mesin negara aplikasi (dinyatakan dalam Roy T. Fieldings PhD disertasi) dengan memiliki alamat sumber daya / URI yang akan berubah seiring waktu, saya akan menyimpulkan bahwa Versi API tidak boleh disimpan di URI sumber daya untuk waktu yang lama yang berarti bahwa sumber daya URI yang dapat bergantung pada pengguna API adalah permalink.

Yakin, dimungkinkan untuk menanamkan versi API di URI dasar tapi hanya untuk penggunaan yang wajar dan terbatas seperti debugging klien API yang berfungsi dengan versi API baru. API berversi seperti itu harus dibatasi waktu dan tersedia untuk kelompok pengguna API terbatas (seperti selama beta tertutup) saja. Jika tidak, Anda berkomitmen sendiri di mana Anda tidak seharusnya.

Beberapa pemikiran tentang pemeliharaan versi API yang memiliki tanggal kedaluwarsa pada mereka. Semua platform / bahasa pemrograman yang biasanya digunakan untuk mengimplementasikan layanan web (Java, .NET, PHP, Perl, Rails, dll.) Memungkinkan pengikatan yang mudah terhadap end-point layanan web ke basis URI. Cara ini sangat mudah berkumpul dan simpan kumpulan file / kelas / metode terpisah di berbagai versi API.

Dari pengguna API POV, itu juga lebih mudah untuk bekerja dengan dan mengikat ke versi API tertentu ketika ini jelas tetapi hanya untuk waktu yang terbatas, yaitu selama pengembangan.

Dari POV pemelihara API, lebih mudah untuk mempertahankan versi API yang berbeda secara paralel dengan menggunakan sistem kontrol sumber yang secara dominan bekerja pada file sebagai unit terkecil dari versi (kode sumber).

Namun, dengan versi API yang terlihat jelas di URI ada peringatan: orang mungkin juga keberatan dengan pendekatan ini sejak Riwayat API menjadi terlihat / jelas dalam desain URI  dan karena itu rentan terhadap perubahan dari waktu ke waktu yang bertentangan dengan pedoman REST. Saya setuju!

Cara untuk mengatasi keberatan yang masuk akal ini, adalah menerapkan versi API terbaru di bawah URI dasar API tanpa versi. Dalam hal ini, pengembang klien API dapat memilih untuk:

  • mengembangkan terhadap yang terbaru (berkomitmen untuk mempertahankan aplikasi yang melindunginya dari perubahan API yang mungkin akan merusaknya klien API yang dirancang dengan buruk).

  • ikat ke versi spesifik API (yang menjadi jelas) tetapi hanya untuk waktu yang terbatas

Misalnya, jika API v3.0 adalah versi API terbaru, dua di antaranya haruslah alias (yaitu bertingkah laku identik dengan semua permintaan API):

http: // shonzilla / api / pelanggan / 1234
http: // shonzilla / api/v3.0/ pelanggan / 1234
http: // shonzilla / api/ v3/ pelanggan / 1234

Selain itu, klien API yang masih mencoba menunjuk ke tua API harus diinformasikan untuk menggunakan versi API terbaru terbaru, jika versi API yang mereka gunakan sudah usang atau tidak didukung lagi. Jadi, akses ke URI yang lama seperti ini:

http: // shonzilla / api/v2.2/ pelanggan / 1234
http: // shonzilla / api/v2.0/ pelanggan / 1234
http: // shonzilla / api/ v2/ pelanggan / 1234
http: // shonzilla / api/v1.1/ pelanggan / 1234
http: // shonzilla / api/ v1/ pelanggan / 1234

harus mengembalikan salah satu 30x kode status HTTP yang menunjukkan pengalihan yang digunakan bersama Location Header HTTP yang mengarahkan ke versi sumber daya URI yang sesuai yang tetap menjadi ini:

http: // shonzilla / api / pelanggan / 1234

Setidaknya ada dua kode status HTTP pengalihan yang sesuai untuk skenario versi API:

  • 301 Dipindahkan secara permanen menunjukkan bahwa sumber daya dengan URI yang diminta dipindahkan secara permanen ke URI lain (yang seharusnya menjadi contoh sumber daya permalink yang tidak berisi info versi API). Kode status ini dapat digunakan untuk menunjukkan versi API yang usang / tidak didukung, menginformasikan kepada klien API bahwa a sumber daya berversi URI telah diganti oleh permalink sumber daya.

  • 302 Ditemukan menunjukkan bahwa sumber daya yang diminta untuk sementara berada di lokasi lain, sementara URI yang diminta mungkin masih didukung. Kode status ini mungkin berguna ketika URI versi-kurang sementara tidak tersedia dan bahwa permintaan harus diulang menggunakan alamat pengalihan (misalnya menunjuk ke URI dengan versi APi tertanam) dan kami ingin memberi tahu klien untuk tetap menggunakannya (yaitu permalinks).

  • skenario lain dapat ditemukan di Redirection 3xx bab dari spesifikasi HTTP 1.1


684
2017-12-29 20:24



URL TIDAK boleh berisi versi. Versi tidak ada hubungannya dengan "ide" dari sumber daya yang Anda minta. Anda harus mencoba memikirkan URL sebagai jalur ke konsep yang Anda inginkan - bukan bagaimana Anda ingin item tersebut dikembalikan. Versi menentukan representasi objek, bukan konsep objek. Seperti kata poster lain, Anda harus menentukan format (termasuk versi) di header permintaan.

Jika Anda melihat permintaan HTTP lengkap untuk URL yang memiliki versi, tampilannya seperti ini:

(BAD WAY TO DO IT):

http://company.com/api/v3.0/customer/123
====>
GET v3.0/customer/123 HTTP/1.1
Accept: application/xml

<====
HTTP/1.1 200 OK
Content-Type: application/xml
<customer version="3.0">
  <name>Neil Armstrong</name>
</customer>

Header berisi baris yang berisi representasi yang Anda minta ("Terima: aplikasi / xml"). Di situlah versi harus pergi. Setiap orang tampaknya mengabaikan fakta bahwa Anda mungkin menginginkan hal yang sama dalam berbagai format dan bahwa klien harus dapat meminta apa yang diinginkannya. Dalam contoh di atas, klien meminta APA SAJA Representasi XML dari sumber daya - bukan representasi sebenarnya dari apa yang diinginkannya. Server dapat, secara teori, mengembalikan sesuatu yang sama sekali tidak terkait dengan permintaan selama itu XML dan itu harus diurai untuk menyadari itu salah.

Cara yang lebih baik adalah:

(GOOD WAY TO DO IT)

http://company.com/api/customer/123
===>
GET /customer/123 HTTP/1.1
Accept: application/vnd.company.myapp.customer-v3+xml

<===
HTTP/1.1 200 OK
Content-Type: application/vnd.company.myapp-v3+xml
<customer>
  <name>Neil Armstrong</name>
</customer>

Lebih lanjut, katakanlah klien berpikir XML terlalu verbose dan sekarang mereka menginginkan JSON sebagai gantinya. Dalam contoh lain, Anda harus memiliki URL baru untuk pelanggan yang sama, sehingga Anda akan mendapatkan:

(BAD)
http://company.com/api/JSONv3.0/customers/123
  or
http://company.com/api/v3.0/customers/123?format="JSON"

(atau yang serupa). Padahal sebenarnya, setiap permintaan HTTP berisi format yang Anda cari:

(GOOD WAY TO DO IT)
===>
GET /customer/123 HTTP/1.1
Accept: application/vnd.company.myapp.customer-v3+json

<===
HTTP/1.1 200 OK
Content-Type: application/vnd.company.myapp-v3+json

{"customer":
  {"name":"Neil Armstrong"}
}

Dengan menggunakan metode ini, Anda memiliki lebih banyak kebebasan dalam desain dan benar-benar mengikuti gagasan asli REST. Anda dapat mengubah versi tanpa mengganggu klien, atau secara bertahap mengubah klien karena API diubah. Jika Anda memilih untuk berhenti mendukung representasi, Anda dapat menanggapi permintaan dengan kode status HTTP atau kode khusus. Klien juga dapat memverifikasi respon dalam format yang benar, dan memvalidasi XML.

Ada banyak kelebihan lain dan saya membahas beberapa di antaranya di blog saya:    http://thereisnorightway.blogspot.com/2011/02/versioning-and-types-in-resthttp-api.html

Salah satu contoh terakhir untuk menunjukkan bagaimana menempatkan versi di URL itu buruk. Katakanlah Anda ingin beberapa informasi di dalam objek, dan Anda telah mengversi berbagai objek Anda (pelanggan v3.0, pesanan v2.0, dan objek shipto adalah v4.2). Berikut adalah URL jahat yang harus Anda berikan di klien:

(Another reason why version in the URL sucks)
http://company.com/api/v3.0/customer/123/v2.0/orders/4321/

273
2017-07-19 16:08



Kami menemukan itu praktis dan berguna untuk menempatkan versi di URL. Ini mempermudah untuk mengetahui apa yang Anda gunakan dalam sekejap. Kami melakukan alias / foo ke / foo / (versi terbaru) untuk kemudahan penggunaan, lebih pendek / URL lebih bersih, dll, seperti yang disarankan oleh jawaban yang diterima.

Menjaga kompatibilitas ke belakang selamanya sering kali mahal dan / atau sangat sulit. Kami lebih suka memberikan pemberitahuan lanjutan tentang penghentian, pengalihan seperti yang disarankan di sini, dokumen, dan mekanisme lainnya.


99
2018-01-04 20:57



Saya setuju bahwa versi representasi sumber daya yang lebih baik mengikuti pendekatan REST ... tetapi, satu masalah besar dengan jenis MIME khusus (atau jenis MIME yang menambahkan parameter versi) adalah dukungan buruk untuk menulis ke header Terima dan Jenis-Konten dalam HTML dan JavaScript.

Misalnya, tidak mungkin IMO ke POST dengan header berikut dalam bentuk HTML5, untuk membuat sumber daya:

Accept: application/vnd.company.myapp-v3+json
Content-Type: application/vnd.company.myapp-v3+json 

Ini karena HTML5 enctype Atribut adalah enumerasi, oleh karena itu hal lain selain yang biasa application/x-www-formurlencoded, multipart/form-data dan text/plain tidak valid.

... atau saya yakin itu didukung di semua browser di HTML4 (yang memiliki atribut encytpe lebih longgar, tetapi akan menjadi masalah implementasi browser, apakah jenis MIME diteruskan)

Karena ini saya sekarang merasa cara yang paling tepat untuk versi adalah melalui URI, tetapi saya menerima bahwa itu bukan cara yang 'benar'.


46
2017-10-13 10:51



Masukkan versi Anda di URI. Satu versi dari suatu API tidak akan selalu mendukung tipe dari yang lain, sehingga argumen bahwa sumber daya hanya bermigrasi dari satu versi ke versi lainnya hanyalah salah. Ini tidak sama dengan beralih format dari XML ke JSON. Tipe-tipe itu mungkin tidak ada, atau mereka mungkin telah berubah secara semantis.

Versi adalah bagian dari alamat sumber daya. Anda melakukan routing dari satu API ke yang lain. Ini tidak RESTful untuk menyembunyikan pengalamatan di header.


21
2018-06-05 15:09



Ada beberapa tempat yang dapat Anda lakukan versi dalam REST API:

  1. Sebagaimana dicatat, di URI. Hal ini dapat diatur dan bahkan estetik menyenangkan jika pengalihan dan sejenisnya digunakan dengan baik.

  2. Di bagian Terima: tajuk, sehingga versinya ada di filetype. Seperti 'mp3' vs 'mp4'. Ini juga akan berfungsi, meskipun IMO bekerja agak kurang baik daripada ...

  3. Di dalam sumber daya itu sendiri. Banyak format file memiliki nomor versi mereka yang disematkan di dalamnya, biasanya di tajuk; ini memungkinkan perangkat lunak baru untuk 'berfungsi' dengan memahami semua versi filetype yang ada saat perangkat lunak yang lebih lama dapat menyepak bola jika versi yang tidak didukung (yang lebih baru) ditentukan. Dalam konteks REST API, itu berarti bahwa URI Anda tidak perlu berubah, hanya tanggapan Anda terhadap versi data tertentu yang Anda berikan.

Saya dapat melihat alasan untuk menggunakan ketiga pendekatan:

  1. jika Anda suka melakukan API baru 'clean sweep', atau untuk perubahan versi utama di mana Anda menginginkan pendekatan semacam itu.
  2. jika Anda ingin klien untuk mengetahui sebelum melakukan PUT / POST apakah itu akan berhasil atau tidak.
  3. jika tidak apa-apa jika klien harus melakukan PUT / POST untuk mengetahui apakah itu akan berhasil.

13
2017-10-24 16:39



Versi API REST Anda analog dengan versi API lainnya. Perubahan kecil dapat dilakukan di tempat, perubahan besar mungkin memerlukan API yang sama sekali baru. Yang paling mudah bagi Anda adalah memulai dari awal setiap saat, yaitu ketika menempatkan versi di URL paling masuk akal. Jika Anda ingin membuat hidup lebih mudah bagi klien Anda mencoba untuk mempertahankan kompatibilitas ke belakang, yang dapat Anda lakukan dengan penghentian (redirect permanen), sumber daya dalam beberapa versi, dll. Ini lebih fiddly dan membutuhkan lebih banyak usaha. Tapi itu juga yang REST mendorong dalam "URI Keren tidak berubah".

Pada akhirnya itu seperti desain API lainnya. Timbang upaya melawan kenyamanan klien. Pertimbangkan untuk mengadopsi versi semantik untuk API Anda, yang membuatnya jelas bagi klien Anda bagaimana kompatibel versi baru Anda.


8
2018-03-06 07:16