Perubahan Besar Buruk! Versi API Baik!
Seperti yang disadari oleh siapa pun yang telah membangun atau secara teratur menggunakan API, perubahan yang merusak sangat buruk dan dapat menjadi aib yang sangat serius pada API yang bermanfaat. Perubahan yang merusak adalah perubahan pada perilaku API yang dapat merusak integrasi pengguna dan mengakibatkan banyak frustrasi serta kehilangan kepercayaan antara penyedia API dan pengguna. Perubahan yang merusak memerlukan bahwa pengguna diberi tahu sebelumnya (dengan ucapan maaf yang menyertai) daripada perubahan yang tiba-tiba muncul, seperti fitur baru yang menyenangkan. Cara untuk menghindari frustrasi tersebut adalah dengan memberikan versi pada API dengan jaminan dari pemilik API bahwa tidak akan ada perubahan mengejutkan yang diperkenalkan dalam satu versi.
Jadi, seberapa sulitkah untuk memberikan versi pada API? Kebenarannya adalah itu tidak sulit, tetapi yang sulit adalah menjaga agar tetap waras dengan tidak secara tidak perlu terjerumus ke dalam sejumlah besar versi dan subversi yang diterapkan di puluhan titik akhir API dengan kompatibilitas yang tidak jelas.
Kami memperkenalkan v1 dari API tiga tahun yang lalu dan tidak menyadari bahwa itu akan terus berlanjut hingga saat ini. Lalu, bagaimana kami terus menyediakan API pengiriman email terbaik selama lebih dari dua tahun tetapi tetap mempertahankan versi API yang sama? Meskipun ada banyak pendapat yang berbeda tentang cara memberikan versi pada REST API, saya harap cerita tentang v1 kami yang sederhana namun kuat dapat memandu Anda menuju pencerahan versi API.
REST adalah yang Terbaik
API SparkPost berasal dari saat kami adalah Sistem Pesan, sebelum petualangan kami di cloud. Pada saat itu kami sibuk melakukan persiapan akhir untuk peluncuran beta Momentum 4. Ini adalah pembaruan besar untuk versi 3.x, MTA terkemuka kami di pasar. Momentum 4 mencakup UI baru yang sepenuhnya, analitik waktu nyata, dan yang paling penting, API web baru untuk penyuntikan dan pembuatan pesan, pengelolaan template, dan pengambilan metrik email. Visi kami adalah arsitektur berorientasi API – di mana bahkan UI akan berinteraksi dengan titik akhir API.
Salah satu keputusan awal dan terbaik yang kami buat adalah mengadopsi gaya RESTful. Sejak akhir 2000-an, transfer status representasional (REST) berbasis web API adalah standar de facto API cloud. Menggunakan HTTP dan JSON membuatnya mudah bagi pengembang, terlepas dari bahasa pemrograman mana yang mereka gunakan – PHP, Ruby, dan Java – untuk berintegrasi dengan API kami tanpa mengetahui atau peduli tentang teknologi dasar kami.
Memilih untuk menggunakan arsitektur RESTful itu mudah. Memilih konvensi versi tidak sesederhana itu. Awalnya kami menghindari pertanyaan tentang versi dengan tidak memberikan versi pada beta sama sekali. Namun, dalam beberapa bulan, beta sudah berada di tangan beberapa pelanggan dan kami mulai membangun layanan cloud kami. Saatnya memberikan versi. Kami mengevaluasi dua konvensi versi. Yang pertama adalah menempatkan versi langsung di URI dan yang kedua adalah menggunakan header Accept. Opsi pertama lebih eksplisit dan kurang rumit, yang lebih mudah bagi para pengembang. Karena kami mencintai pengembang, itu adalah pilihan logis.
Pemerintahan API
Dengan konvensi versi yang dipilih, kami memiliki lebih banyak pertanyaan. Kapan kami akan meningkatkan versi? Apa itu perubahan yang merusak? Apakah kami akan mengubah seluruh API atau hanya titik akhir tertentu? Di SparkPost, kami memiliki beberapa tim yang bekerja pada bagian yang berbeda dari API kami. Di dalam tim tersebut, orang-orang bekerja pada titik akhir yang berbeda pada waktu yang berbeda. Oleh karena itu, sangat penting bahwa API kami konsisten dalam penggunaan konvensi. Ini lebih besar daripada sekadar versi.
Kami membentuk kelompok pemerintahan yang terdiri dari insinyur yang mewakili setiap tim, seorang anggota tim Manajemen Produk, dan CTO kami. Kelompok ini bertanggung jawab untuk menetapkan, mendokumentasikan, dan menegakkan konvensi API kami di seluruh tim. Saluran Slack pemerintahan API juga berguna untuk debat hidup tentang topik ini.
Kelompok pemerintahan mengidentifikasi sejumlah cara perubahan dapat diperkenalkan ke API yang bermanfaat bagi pengguna dan tidak termasuk perubahan yang merusak. Ini termasuk:
Sumber daya atau titik akhir API baru
Parameter opsional baru
Perubahan pada titik akhir API yang tidak publik
Kunci opsional baru dalam badan POST JSON
Kunci baru yang dikembalikan dalam badan respons JSON
Sebaliknya, perubahan yang merusak mencakup apa pun yang dapat merusak integrasi pengguna seperti:
Parameter baru yang diwajibkan
Kunci baru yang diwajibkan dalam tubuh POST
Pencabutan titik akhir yang ada
Pencabutan metode permintaan titik akhir yang ada
Perilaku internal API yang secara material berbeda – seperti perubahan perilaku default.
Yang Besar 1.0
Saat kami mendokumentasikan dan mendiskusikan konvensi ini, kami juga sampai pada kesimpulan bahwa demi kepentingan bersama (termasuk kepentingan kami!) sangat penting untuk menghindari membuat perubahan yang merusak pada API karena pengelolaan beberapa versi menambah cukup banyak beban. Kami memutuskan bahwa ada beberapa hal yang harus kami perbaiki dengan API kami sebelum berkomitmen untuk “v1”.
Mengirim email sederhana membutuhkan terlalu banyak usaha. Untuk “menjaga hal-hal sederhana tetap sederhana,” kami memperbarui tubuh POST untuk memastikan bahwa baik kasus penggunaan sederhana maupun kompleks dapat terakomodasi. Format baru juga lebih tahan masa depan. Kedua, kami mengatasi masalah dengan titik akhir Metrik. Titik akhir ini menggunakan parameter “group_by” yang akan mengubah format badan respons GET sehingga kunci pertama akan menjadi nilai dari parameter group by. Itu tidak terlihat sangat RESTful jadi kami memisahkan setiap grup berdasarkan ke dalam titik akhir terpisah. Akhirnya, kami mengaudit setiap titik akhir dan melakukan perubahan kecil di sana-sini untuk memastikan agar sesuai dengan standar.
Dokumentasi Akurat
Penting untuk memiliki dokumentasi API yang akurat dan dapat digunakan untuk menghindari perubahan yang merusak, baik yang disengaja maupun tidak. Kami memutuskan untuk menggunakan pendekatan dokumentasi API yang sederhana dengan memanfaatkan bahasa Markdown yang disebut API Blueprint dan mengelola dokumen kami di Github. Komunitas kami menyumbang dan memperbaiki dokumen sumber terbuka ini. Kami juga memelihara set dokumen tidak publik di Github untuk API dan titik akhir internal.
Pada awalnya, kami menerbitkan dokumen kami ke Apiary, alat hebat untuk prototipe dan menerbitkan dokumen API. Namun, menyematkan Apiary ke situs web kami tidak berfungsi pada perangkat seluler sehingga kami sekarang menggunakan Jekyll untuk menghasilkan dokumen statis sebagai pengganti. Dokumen API SparkPost terbaru kami sekarang dimuat dengan cepat dan berfungsi baik di perangkat seluler, yang penting bagi pengembang yang tidak selalu duduk di depan komputer mereka.
Memisahkan Penyebaran dari Rilis
Kami belajar lebih awal trik berharga memisahkan penyebaran dari rilis. Dengan cara ini, mungkin untuk sering menyebarkan perubahan saat siap melalui pengiriman dan penyebaran berkelanjutan tetapi kami tidak selalu mengumumkan atau mendokumentasikannya secara publik pada saat yang sama. Tidak jarang bagi kami untuk menyebarkan titik akhir API baru atau peningkatan pada titik akhir API yang ada dan menggunakannya dari dalam UI atau dengan alat internal sebelum kami mendokumentasikannya dan mendukungnya secara publik. Dengan cara ini kami dapat melakukan beberapa penyesuaian untuk penggunaan atau kesesuaian dengan standar tanpa khawatir membuat perubahan yang tidak diinginkan. Setelah kami puas dengan perubahannya, kami menambahkannya ke dokumentasi publik kami.
Duh!
Sangat adil untuk mengakui bahwa ada kalanya kami tidak memenuhi cita-cita “tidak ada perubahan yang merusak” kami dan ini layak untuk dipelajari. Pada suatu kali kami memutuskan bahwa akan lebih baik bagi pengguna jika properti tertentu default ke true ketimbang false. Setelah kami menyebarkan perubahan tersebut, kami menerima beberapa keluhan dari pengguna karena perilakunya telah berubah secara tidak terduga. Kami membalikkan perubahan tersebut dan menambahkan pengaturan di tingkat akun – pendekatan yang jauh lebih ramah pengguna tentu saja.
Kadang-kadang kami tergoda untuk memperkenalkan perubahan yang merusak sebagai akibat dari perbaikan bug. Namun, kami memutuskan untuk membiarkan idiosinkrasi ini tidak terganggu daripada mengambil risiko merusak integrasi pelanggan demi konsistensi.
Ada kasus langka di mana kami membuat keputusan serius untuk melakukan perubahan yang merusak – seperti menghapus sumber daya atau metode API – demi kepentingan komunitas pengguna yang lebih besar dan hanya setelah mengonfirmasi bahwa dampaknya sangat sedikit atau tidak ada bagi pengguna. Misalnya, kami dengan sengaja membuat keputusan untuk mengubah perilaku respons API Penghapusan tetapi hanya setelah mempertimbangkan dengan cermat manfaat dan dampaknya bagi komunitas dan secara hati-hati mengkomunikasikan perubahan tersebut kepada pengguna kami. Namun, kami tidak akan pernah memperkenalkan perubahan yang memiliki kemungkinan jauh untuk langsung mempengaruhi pengiriman email produksi pengguna.