Transisi ke arsitektur layanan mikro memerlukan revisi pendekatan untuk pengembangan, pengujian, pemeliharaan, desain - dengan kata lain, untuk semua aspek siklus hidup komponen perangkat lunak. Dalam posting ini, kita akan berbicara tentang praktik yang dilakukan tim arsitek Acronis dalam bergerak menuju API komponen terbaik. Kisah ini akan mencakup pernyataan masalah dan analisis solusinya. Mungkin posting ini akan menjadi “kapten” bagi sebagian orang, tidak akan jelas bagi seseorang mengapa mereka melewatkan solusi-super X, tetapi kami berharap ini akan menarik dan bermanfaat bagi Anda. Kami mengundang pembuat microservice untuk membaca dan meninggalkan komentar Anda di bawah cat.

Jika Anda berlangganan blog kami, Anda sudah membaca tentang kontrak layanan mikro. Kami berbicara tentang mereka dalam posting tentang memilih
Swagger atau RAML , serta
pemeriksaan statis yang dapat dilakukan berdasarkan anotasi yang dibuat sebelumnya. Alasan posting hari ini adalah
laporan di konferensi HighLoad . Kami perlu secara umum berbicara tentang jalan yang kami tempuh untuk meresmikan hubungan antara layanan-layanan mikro. Dan hari ini saya ingin membagikan kesimpulan kami dengan Habr, dan juga untuk memeriksa apakah arsitek lain setuju dengan kami.
Layanan Microsoft adalah "batu bata" tempat pengembang membuat aplikasi modern. Setiap layanan tersebut berinteraksi dengan dunia luar melalui API. Biasanya, layanan mikro dikembangkan oleh tim terpisah, terkadang tersebar secara geografis, sehingga untuk pekerjaan yang efektif perlu menjaga konsistensi dan integritas antarmuka publik mereka. Di perusahaan besar dengan ratusan layanan, perlu memiliki anotasi dari masing-masing komponen: memformalkan data input dan menjelaskan secara terperinci hasil pekerjaannya. Jika Anda bekerja dengan HTTP REST, maka ada dua format anotasi umum untuk ini: RAML dan Spesifikasi Open API (alias Swagger). Tetapi pertanyaan-pertanyaan yang kami fokuskan hari ini tidak terikat dengan protokol tertentu. Oleh karena itu, yang berikut akan relevan bahkan untuk gRPC.
Latar belakang
Acronis telah ada selama lebih dari 15 tahun. Selama ini, produk dan basis kode telah berevolusi secara signifikan. Dari aplikasi desktop yang kompleks, kami sampai pada model perusahaan dengan konsol manajemen terpusat, pembatasan hak, dan log audit. Langkah selanjutnya adalah transformasi aplikasi perusahaan menjadi platform terbuka, di mana akumulasi pengalaman digunakan untuk berintegrasi dengan layanan eksternal.
Jika sebelum API penting, sekarang telah menjadi komponen penting dari produk. Dan proses yang disediakan API ini telah matang.
Masalah besar
Masalah seputar bangunan API tampak familier bagi semua orang. Kami akan menggambarkan mereka dalam bentuk hipertrofi: sebagai rasa sakit yang menyiksa programmer hipotetis Vasya dan manajernya yang tidak kurang hipotetis Kolya. Semua nama adalah fiktif, dan setiap kecocokan tidak disengaja :)
1. Deskripsi sudah usangBiarkan programmer Vasya mengembangkan komponen A, yang menggunakan API komponen B. Yang terakhir memiliki anotasi, tetapi tidak valid. Vasya harus merangkak ke kode orang lain, mencari orang, bertanya. Tenggat waktu sedang keluar, dan manajernya Kolya harus berurusan dengan transfer tenggat waktu.
2. API tidak konsistenProgrammer Vasya menyelesaikan tugas dan beralih ke yang berikutnya terkait dengan pengoperasian komponen B. Namun, baik pengembang B dan pengembang C memiliki perasaan keindahan yang berbeda, sehingga hal yang sama dilakukan secara berbeda dalam API. Vasya kembali berurusan dengan kode, dan lagi-lagi Kolya menderita gagal memenuhi tenggat waktu.
3. API tidak didokumentasikanManajer Kolya memutuskan untuk menerbitkan API komponen A sehingga integrator dapat membuat integrasi yang luar biasa. Integrator dihadapkan dengan masalah, layanan dukungan kelebihan beban, semuanya terbakar dengan manajer Kolya, dan Vasya merasa bahwa gilirannya akan segera datang.
4. API tidak kompatibel dengan versi lama.Integrasi diterapkan, semua kebakaran padam. Tapi Vasya tiba-tiba memutuskan bahwa API komponennya jauh dari sempurna dan tenggelam dalam revisi. Tentu saja, dalam hal ini kompatibilitas ke belakang dilanggar dan semua integrasi berantakan. Situasi ini menyebabkan biaya pada bagian integrator dan hilangnya uang oleh perusahaan pengembangan.
Metode pengobatan
Semua masalah ini muncul ketika programmer tidak tahu tentang REST API yang baik atau tampilan ini terpecah-pecah. Pada kenyataannya, tidak semua pengembang memiliki pengalaman dengan REST. Dan karena itu, metode utama "perawatan" ditujukan untuk pendidikan. Ketika visi API yang tepat, yang dikoordinasikan dengan visi pengembang lain, arsitek, dan dokumenter, mulai mual di kepala setiap pengembang, API menjadi ideal. Proses pembentukan visi ini membutuhkan upaya dan alat khusus, yang sekarang akan kita bicarakan.
Nyeri 1. Anotasi tidak sesuai dengan implementasi
Anotasi mungkin berbeda dari kondisi layanan saat ini tidak hanya karena itu adalah API dari "masa lalu yang gelap", yang tidak dapat dijangkau. Ini juga bisa menjadi API masa depan yang cerah yang belum tiba.
Alasan untuk kondisi ini adalah kurangnya pemahaman tentang mengapa anotasi diperlukan. Tanpa teror dari pihak arsitek, pengembang cenderung menganggap anotasi sebagai alat bantu internal dan tidak menyiratkan bahwa seseorang di luar akan menggunakannya.
Anda dapat menyembuhkan rasa sakit ini dengan:
- Ulasan arsitektur. Suatu hal yang sangat berguna bagi perusahaan dari semua ukuran, di mana setidaknya ada satu programmer yang "tahu bagaimana melakukannya dengan benar". Saat mengganti layanan, arsitek atau penanggung jawab harus memantau status anotasi dan mengingatkan programmer bahwa perlu memperbarui tidak hanya layanan, tetapi juga deskripsinya. Efek samping - hambatan dalam wajah arsitek
- Pembuatan kode dari anotasi. Inilah yang disebut pendekatan API-first. Ini menyiratkan bahwa Anda awalnya membuat anotasi, kemudian menghasilkan kode utama (ada cukup alat untuk ini, misalnya [go-swagger] (https://github.com/go-swagger/go-swagger)), dan kemudian mengisi layanan bisnis logika Pengaturan ini menghindari ketidakkonsistenan. Ini bekerja dengan baik ketika bidang tugas yang diselesaikan oleh layanan jelas digambarkan.
- Menguji anotasi versus implementasi . Untuk melakukan ini, kami menghasilkan dari anotasi (RAML / kesombongan) klien yang membombardir layanan dengan permintaan. Jika jawaban sesuai dengan anotasi, dan layanan itu sendiri tidak jatuh, maka semuanya baik-baik saja.
Menguji anotasi vs implementasiMari kita coba pengujian. Pembuatan kueri yang sepenuhnya otomatis semacam itu adalah tugas yang kompleks. Memiliki data dari anotasi API, Anda dapat membuat permintaan terpisah. Namun, API apa pun menyiratkan dependensi, misalnya, sebelum memanggil GET / klien / {cliend_id} Anda harus membuat objek ini terlebih dahulu dan kemudian mendapatkan id. Kadang-kadang dependensi kurang eksplisit - membuat objek X memerlukan melewati pengidentifikasi objek terkait Y, dan ini bukan sub-koleksi. Baik RAML maupun Swagger memungkinkan dependensi eksplisit untuk dijelaskan. Oleh karena itu, beberapa pendekatan mungkin dilakukan di sini:
- Harapkan komentar formal dari pengembang dalam anotasi yang mengindikasikan dependensi.
- Untuk meminta deskripsi urutan yang diharapkan dari pengembang (ada beberapa cara untuk menggambarkan permintaan menggunakan YAML , DSL khusus , atau melalui GUI yang indah, seperti yang dilakukan oleh orang yang ditinggalkan sekarang.
- Ambil data nyata (misalnya, menggunakan OpenResty untuk mencatat semua permintaan dan respons server)
- Ekstrak dependensi dari anotasi menggunakan (hampir) kecerdasan buatan (mis. RESTler )
Bagaimanapun, tugas pengujian sangat memakan waktu.

Secara pribadi, kami sampai pada titik mempersiapkan urutan pengujian secara manual. Bagaimanapun, pengembang perlu menulis tes, sehingga kami dapat menyediakan mereka dengan alat yang nyaman yang dapat menemukan beberapa bug tambahan.
Utilitas kami menggunakan yaml berikut untuk menggambarkan urutan permintaan:

Kurung keriting menyatakan variabel yang disubstitusikan selama pengujian. Variabel alamat dilewatkan sebagai parameter CLI, dan acak menghasilkan string arbitrer. Yang paling menarik di sini adalah bidang response-to-var: berisi variabel di mana json akan ditulis dengan respons server. Dengan demikian, di baris terakhir, Anda bisa mendapatkan id dari objek yang dibuat menggunakan task.id.
Nyeri 2. API tidak konsisten
Apa itu konsistensi? Kami tidak akan memperkenalkan definisi formal apa pun, tetapi, menyederhanakan, ini adalah konsistensi internal. Misalnya, dalam proyek awal, Vasya perlu mengumpulkan data laporan di HighLoad, dan API menyediakan pemfilteran data berdasarkan tahun. Setelah proyek hampir selesai, manajer Kolya datang ke Vasya dengan permintaan untuk menambahkan statistik pada pembicara untuk analisis, dan untuk membuat metode baru "GET speaker" juga dengan penyaringan berdasarkan tahun. Akibatnya, Vasya menyelesaikan kode dalam beberapa jam, tetapi selama proses pengujian ternyata metode ini tidak berfungsi. Alasannya adalah bahwa dalam satu kasus, "tahun" adalah angka, di lain, string. Tapi ini, tentu saja, tidak jelas pada pandangan pertama dan membutuhkan perawatan yang konstan saat bekerja dengan API. Kegigihan API adalah ketika perawatan berlebihan seperti itu tidak diperlukan.
Ada banyak contoh ketidakkonsistenan:
- penggunaan format berbeda dari data yang sama. Misalnya, format waktu, jenis pengidentifikasi (nomor atau string UUID),
- menerapkan sintaks yang berbeda untuk penyaringan atau pagination,
- skema otorisasi berbeda untuk layanan. Tidak hanya perbedaan otak pemrogram bedak, mereka juga bercermin pada tes yang perlu mendukung skema yang berbeda.
Pengobatan :
- Ulasan arsitektur. Jika ada arsitek tiran, ia (tanpa adanya skizofrenia) akan memastikan konsistensi. Efek samping: faktor bus dan tirani :)
- Membuat API Pedoman. Ini adalah standar tunggal yang perlu dikembangkan (atau disiapkan), tetapi yang paling penting adalah untuk menerapkannya. Ini membutuhkan propaganda, tongkat, dan wortel.
- Penerapan pemeriksaan statis untuk kepatuhan dengan Pedoman API anotasi (baca di sini ).
Contoh - Item Tes StatisSetiap perusahaan membuat pilihannya sendiri untuk menggunakan Pedoman mana. Dan, mungkin, tidak ada pendekatan universal, apa yang seharusnya dan apa yang tidak. Lagi pula, semakin banyak ketentuan dalam standar, semakin ketat Anda mengendalikan dan semakin Anda membatasi kebebasan kreativitas. Dan yang paling penting, sedikit orang membaca sampai akhir dokumen "hanya 100 halaman".
Di perusahaan kami, kami memasukkan poin-poin berikut dalam pedoman:

Contoh Pedoman bagus lainnya dapat ditemukan di
Microsoft ,
PayPal ,
Google .
Nyeri 3. API tidak didokumentasikan
Keberadaan anotasi adalah syarat yang diperlukan tetapi tidak cukup untuk kesederhanaan bekerja dengan API. Anda dapat menulis anotasi sehingga tidak menyadari potensi penuhnya. Ini terjadi ketika:
- tidak cukup deskripsi (untuk parameter, header, kesalahan, dll.);
- tidak ada cukup contoh penggunaan, karena contoh dapat digunakan tidak hanya untuk meningkatkan dokumentasi (lebih banyak konteks untuk pengembang dan kemampuan untuk bermain langsung dengan API langsung dari portal), tetapi juga untuk pengujian (sebagai titik awal untuk fuzzing));
- ada fitur tidak berdokumen.
Biasanya ini terjadi ketika pengembang tidak memiliki pemahaman yang jelas tentang mengapa anotasi yang diperlukan diperlukan, ketika tidak ada komunikasi antara penulis teknis dan programmer, dan juga jika tidak ada yang tahu berapa biaya perusahaan dengan dokumentasi yang buruk. Dan jika mereka datang ke programmer dan menarik setelah setiap permintaan dukungan, semua anotasi akan diisi dengan sangat cepat.
Pengobatan:- Ketersediaan alat penghasil referensi API untuk programmer. Jika pengembang melihat seperti apa uraian API-nya bagi kolega dan pengguna, ia akan mencoba membuat anotasi lebih baik. Efek samping: Mengkonfigurasi alat-alat ini akan membutuhkan pekerjaan manual tambahan.
- Mengatur interaksi antara semua yang terlibat : programmer, penginjil, staf pendukung. Efek samping: bertemu semua orang dengan semua orang, proses yang rumit.
- Menggunakan tes berdasarkan anotasi API . Penerapan pemeriksaan statis di atas dalam repositori CI dengan anotasi.
Di Acronis, API anotasi dihasilkan berdasarkan anotasi dengan klien SDK dan bagian Try-It. Bersama-sama dengan contoh kode dan deskripsi kasus penggunaan, mereka membentuk berbagai tambahan yang diperlukan dan nyaman untuk programmer. Lihat portal kami di developer.acronis.com

Saya harus mengatakan bahwa ada seluruh kelas alat untuk menghasilkan referensi API. Beberapa perusahaan sendiri mengembangkan alat tersebut untuk kebutuhan mereka sendiri. Lainnya menggunakan alat yang cukup sederhana dan gratis seperti
Editor Swagger . Setelah penelitian yang sangat panjang, kami di Acronis memilih Apimatic.io, lebih memilihnya daripada REST United, Mulesoft AnyPoint, dan lainnya.
Nyeri 4. Masalah kompatibilitas ke belakang
Kompatibilitas mundur mungkin terganggu karena hal-hal sepele. Sebagai contoh, programmer Vasya menulis kata kompatibilitas setiap kali dengan kesalahan ketik: kompatibilitas. Kesalahan ketik ini ditemukan dalam kode, di komentar, dan dalam satu parameter kueri. Setelah melihat kesalahan, Vasya membuat penggantian kata ini di seluruh proyek dan tanpa melihat mengirimkan perubahan ke produksi. Tentu saja, kompatibilitas ke belakang akan terganggu dan layanan akan turun selama beberapa jam.
Mengapa peristiwa seperti itu bisa terjadi? Alasan utamanya adalah kesalahpahaman dari siklus hidup API, yang dapat memanifestasikan dirinya dalam melanggar integrasi, dalam kebijakan EOL (End Of Life) yang tidak dapat diprediksi, dan dalam rilis API yang tidak jelas.
Pengobatan:- Ulasan arsitektur. Seperti biasa, tangan tegas seorang arsitek dapat mencegah kompatibilitas ke belakang. Namun, tugas utamanya adalah menjelaskan biaya untuk mendukung beberapa versi dan mencari opsi untuk membuat perubahan tanpa melanggar API yang ada.
- Pemeriksaan kompatibilitas mundur. Jika anotasi API berisi uraian terbaru, maka pelanggaran kompatibilitas mundur dapat diperiksa pada tahap CI;
- Pembaruan dokumentasi tepat waktu. Referensi API dan deskripsi API harus diperbarui pada saat yang sama ketika kode layanan berubah. Untuk melakukan ini, Anda setidaknya dapat memulai daftar periksa standar, setidaknya mengatur pemberitahuan untuk perubahan, setidaknya melatih kemampuan super untuk menghasilkan segalanya dari segalanya ... Penting! Departemen dokumentasi harus mengetahui semua perubahan yang direncanakan sehingga mereka memiliki kesempatan untuk merencanakan sumber daya untuk memperbarui dokumentasi dan menulis panduan peningkatan. Panduan Upgrade, diuji dan diverifikasi, adalah atribut menyedihkan dari penggantian nama yang Anda mulai di API.
Ubah manajemen
Aturan yang menggambarkan aktivitas yang terkait dengan siklus hidup API disebut kebijakan manajemen perubahan.

Jika Anda memiliki dua versi anotasi "saat ini" dan "baru", pemeriksaan kompatibilitas mundur secara teknis sederhana: cukup uraikan kedua anotasi dan periksa apakah bidang yang diperlukan ada

Kami menulis alat khusus yang memungkinkan Anda untuk membandingkan semua parameter penting untuk kompatibilitas mundur di CI. Misalnya, ketika mengubah badan tanggapan dalam permintaan cek kesehatan / GET, pesan yang mirip dengan yang berikut ini akan ditampilkan:

Kesimpulan
Setiap arsitek bermimpi untuk menyingkirkan masalah API. Setiap manajer bermimpi tidak tahu tentang masalah API. :) Ada banyak obat, tetapi masing-masing memiliki harga sendiri dan efek sampingnya. Kami berbagi opsi perawatan kami untuk penyakit anak-anak yang paling sederhana dengan API, dan kemudian timbul masalah yang lebih serius. Kesimpulan dari artikel kami "kapten": Masalah API dimulai dengan kepala dan mengajar orang praktik yang baik adalah jaminan utama kesuksesan. Yang lainnya hanyalah masalah teknologi. Dan masalah apa yang Anda hadapi dan solusi apa yang Anda pilih di organisasi Anda?
Obat untuk API buruk.Kami akan senang dengan segala pemikiran, peringkat, komentar, pendapat dan pertanyaan!