Nama saya Andrey Polyakov, saya adalah kepala grup dokumentasi API dan SDK di Yandex. Hari ini saya ingin berbagi dengan Anda sebuah laporan yang saya dan rekan saya, pengembang dokumentasi senior Julia Pivovarova, baca beberapa minggu lalu di Hyperbaton keenam.
Svetlana Kayushina, kepala departemen dokumentasi dan lokalisasi:
- Volume kode program di dunia dalam beberapa tahun terakhir telah tumbuh secara signifikan, terus tumbuh, dan ini memengaruhi pekerjaan penulis teknis, yang memiliki semakin banyak tugas untuk mengembangkan dokumentasi program dan kode dokumen. Kami tidak bisa mengabaikan topik ini, kami mencurahkan seluruh bagian untuk itu. Ini adalah tiga laporan terkait tentang penyatuan pengembangan perangkat lunak. Saya mengundang spesialis kami dalam mendokumentasikan antarmuka perangkat lunak dan perpustakaan ke Andrei Polyakov dan Julia Pivovarova. Saya memberi mereka lantai.
- Halo semuanya! Hari ini, Julia dan saya akan memberi tahu Anda bagaimana di Yandex kami mendapatkan pandangan baru tentang mendokumentasikan API dan SDK. Laporan akan terdiri dari empat bagian, laporan pengawasan, kami akan membahas, kami akan berbicara.
Mari kita bicara tentang penyatuan API dan SDK, bagaimana kita mendapatkannya, apa yang kita lakukan di sana. Kami akan berbagi pengalaman menggunakan generator universal, satu untuk semua bahasa, dan memberi tahu Anda mengapa itu tidak cocok untuk kami, apa perangkapnya, dan mengapa kami beralih ke generasi dokumentasi oleh generator asli.
Pada akhirnya, kami akan menjelaskan bagaimana proses kami dibangun.
Mari kita mulai dengan penyatuan. Semua orang berpikir tentang penyatuan ketika ada lebih dari dua orang dalam sebuah tim: setiap orang menulis secara berbeda, setiap orang memiliki pendekatan mereka sendiri, dan ini logis. Lebih baik mendiskusikan semua aturan di pantai sebelum Anda mulai menulis dokumentasi, tetapi tidak semua orang bisa melakukannya.
Kami mengumpulkan kelompok ahli untuk menganalisis dokumentasi kami. Kami melakukan ini untuk mensistematisasikan pendekatan kami. Semua orang menulis dengan cara yang berbeda, dan mari kita sepakat untuk menulis dengan gaya yang sama. Ini adalah poin kedua, di mana kami akan mencoba membuat seragam dokumentasi, sehingga pengguna memiliki satu pengalaman pengguna dalam semua dokumentasi Yandex, yaitu teknis.
Pekerjaan itu dibagi menjadi tiga tahap. Kami telah menyusun uraian tentang teknologi yang kami gunakan di Yandex, kami mencoba memilih yang bisa kami satukan. Dan juga membuat struktur umum dokumen dan templat standar.

Mari kita beralih ke deskripsi teknologi. Kami mulai mempelajari teknologi apa yang digunakan di Yandex. Ada begitu banyak dari mereka yang kami lelah menuliskannya di beberapa jenis notebook, dan sebagai hasilnya, kami memilih hanya yang paling dasar yang paling sering digunakan, yang paling sering ditemui penulis teknis, dan mulai menggambarkannya.
Apa yang dimaksud dengan deskripsi teknologi? Kami telah mengidentifikasi poin utama dan esensi dari setiap teknologi. Jika kita berbicara tentang bahasa pemrograman, maka ini adalah deskripsi entitas seperti kelas, properti, antarmuka, dll. Jika kita berbicara tentang protokol, kita menjelaskan metode HTTP, kita berbicara tentang format kode kesalahan, kode respons, dll. Kami membuat glosarium berisi hal-hal berikut: istilah dalam bahasa Rusia, istilah dalam bahasa Inggris, nuansa penggunaan. Sebagai contoh, kami tidak berbicara tentang metode SDK, yang memungkinkan Anda untuk melakukan sesuatu. Dia MELAKUKAN sesuatu, jika programmer menarik beberapa pena, itu memberikan beberapa jawaban.
Selain nuansa, deskripsi juga berisi struktur standar, giliran bicara standar, yang kami gunakan dalam dokumentasi sehingga penulis teknis dapat mengambil kata-kata tertentu dan menggunakannya lebih lanjut.
Selain itu, penulis teknis sering menulis potongan kode, cuplikan, sampel, dan untuk ini kami juga menjelaskan panduan gaya kami untuk setiap teknologi. Kami membuka panduan pengembang yang ada di Yandex. Kami memperhatikan kode desain, deskripsi komentar, lekukan dan semua itu. Kami melakukan ini sehingga ketika seorang penulis teknis datang dengan sepotong kode atau sampel tertulis kepada seorang programmer, programmer melihat esensi, dan bukan pada bagaimana itu dirancang, dan ini mengurangi waktu. Dan ketika seorang penulis teknis dapat menulis pada panduan gaya Yandex, itu sangat keren, mungkin dia ingin menjadi seorang programmer nantinya. Laporan sebelumnya adalah tentang berbagai pemeriksaan. Misalnya, Anda dapat pindah ke pemrogram.
Kami juga mengembangkan awal yang cepat untuk para penulis teknologi: cara mengatur lingkungan pengembangan ketika ia menjadi akrab dengan teknologi baru. Misalnya, jika penulis teknis SDK ditulis dalam C #, maka ia datang, mengatur lingkungan pengembangan, membaca manual, berkenalan dengan terminologi. Kami juga meninggalkan tautan ke dokumentasi resmi dan RFC, jika ada. Kami membuat titik masuk untuk penulis teknis, dan terlihat seperti ini.

Ketika seorang penulis teknis tiba, ia belajar teknologi baru dan mulai mendokumentasikannya.
Setelah kami menjelaskan teknologi, kami melanjutkan untuk menggambarkan struktur API HTTP.
Kami memiliki banyak API HTTP yang berbeda, dan semuanya dijelaskan secara berbeda. Mari kita membuat perjanjian dan melakukan hal yang sama!
Kami telah mengidentifikasi bagian utama yang akan ada di setiap HTTP API:

“Tinjauan Umum” atau “Pendahuluan”: mengapa API ini diperlukan, apa yang memungkinkan Anda lakukan, host mana yang harus diakses untuk mendapatkan semacam jawaban.
"Mulai cepat" ketika seseorang melewati beberapa langkah dan mendapatkan hasil yang sukses di akhir untuk memahami cara kerja API ini.
"Koneksi / Otorisasi". Banyak API membutuhkan token otorisasi atau kunci API. Ini adalah poin penting, jadi kami memutuskan bahwa ini adalah bagian wajib dari semua API.
“Batasan / Batas” ketika kita berbicara tentang batasan jumlah permintaan atau pada ukuran badan permintaan, dll.
"Referensi", referensi. Bagian yang sangat besar, yang berisi semua pegangan HTTP yang dapat ditarik pengguna dan mendapatkan semacam hasil.

Akibatnya, kami memiliki banyak API yang berbeda, mereka dideskripsikan secara berbeda, sekarang kami mencoba menulis semuanya dengan cara yang sama. Keuntungan seperti itu.
Menuju ke direktori, kami menyadari bahwa gagang HTTP hampir selalu sama. Anda menariknya, yaitu, Anda membuat permintaan, server mengembalikan jawaban - voila. Mari kita coba menyatukannya. Kami menulis templat yang mencoba menutupi semua kasus. Penulis teknis mengambil templat, dan jika ia memiliki permintaan PUT, ia meninggalkan bagian yang diperlukan dalam templat. Jika ia memiliki permintaan GET, ia hanya menggunakan bagian-bagian yang diperlukan untuk permintaan GET. Template umum untuk semua permintaan yang dapat digunakan kembali. Sekarang Anda tidak perlu membuat struktur dokumen dari awal, tetapi Anda bisa mengambil template yang sudah jadi.

Setiap pena menjelaskan untuk apa, untuk apa. Ada bagian "Format permintaan", yang berisi parameter-path, parameter-kueri, semua yang ada di badan permintaan jika dikirim. Kami juga menyoroti bagian "Format respons": kami menulisnya jika ada badan tanggapan. Sebagai bagian terpisah, kami menyoroti "Kode Respon", karena respons dari server datang secara independen dari tubuh. Dan meninggalkan bagian "Contoh". Jika kami menyediakan semacam SDK dengan API ini, maka kami katakan bahwa gunakan SDK ini seperti ini, tarik pegangan seperti itu, panggil metode seperti itu. Biasanya kita meninggalkan semacam contoh CURL di mana pengguna cukup memasukkan token-nya. Dan jika kita memiliki bangku tes, itu hanya membutuhkan permintaan dan menjalankannya. Dan mendapat semacam hasil.

Ternyata ada banyak pena, mereka dijelaskan dengan cara yang berbeda, dan sekarang kami ingin membawa semuanya ke satu bentuk.
Setelah kami selesai dengan API HTTP, kami pindah ke SDK seluler.
Ada struktur dokumen umum, kira-kira sama:
- "Pendahuluan", di mana kami mengatakan bahwa, di sini, SDK ini digunakan untuk tujuan tersebut, mengintegrasikannya untuk diri sendiri untuk tujuan tersebut, cocok untuk OS tersebut, kami memiliki versi ini dan itu, dll
- "Koneksi". Tidak seperti HTTP API, kami tidak hanya berbicara bagaimana cara mendapatkan kunci untuk menggunakan SDK, jika Anda membutuhkannya, kami berbicara tentang bagaimana mengintegrasikan perpustakaan ke dalam proyek kami.
- "Contoh penggunaan." Bagian volume terbesar. Paling sering, pengembang ingin datang ke dokumentasi dan tidak membaca banyak informasi, mereka ingin menyalin sepotong, menempelkannya sendiri, dan semuanya akan bekerja untuk mereka. Oleh karena itu, kami menganggap bagian ini sangat penting dan mengalokasikannya ke bagian wajib.

- "Direktori", referensi, tetapi tidak seperti referensi HTTP API, kami tidak dapat menyatukan semuanya di sini, karena kami terutama menghasilkan direktori dan kami akan membicarakannya nanti dalam laporan.
- "Rilis," atau ubah riwayat, changelog. SDK seluler biasanya memiliki siklus rilis singkat, versi baru dirilis setiap dua minggu. Dan akan lebih baik bagi pengguna untuk berbicara tentang apa yang telah berubah, apakah itu layak untuk diperbarui atau tidak.
Pada saat yang sama, API memiliki bagian yang diperlukan yang kami lihat dan bagian yang kami sarankan untuk digunakan. Jika API sering diperbarui, kami katakan itu kemudian masukkan sendiri juga riwayat perubahan, yang telah berubah di API. Dan seringkali API kami jarang diperbarui, dan tidak ada gunanya untuk menunjukkan ini sebagai bagian yang diperlukan.

Jadi, kami memiliki banyak SDK yang dijelaskan dengan cara yang berbeda, kami mencoba mengubahnya menjadi kira-kira dengan gaya yang sama. Secara alami, ada perbedaan tambahan yang hanya melekat pada SDK ini atau API HTTP ini. Di sini kita memiliki kebebasan untuk memilih. Kami tidak mengatakan bahwa selain bagian ini, tidak ada yang bisa dilakukan. Tentu saja, itu mungkin, kami hanya mencoba melakukan bagian yang terdaftar di mana-mana sehingga jelas bahwa jika pengguna beralih ke SDK lain dalam dokumentasi, ia tahu apa yang akan dijelaskan di bagian "Sambungan".
Jadi, kami membuat templat, membuat panduan, apa rencana aksi kami sekarang? Kami memutuskan bahwa jika kami menskalakan API, mengganti pena atau mengubah SDK, kami mengambil template baru, mengambil struktur baru dan mulai mengerjakannya.
Jika kita menulis dokumentasi dari awal, maka, tentu saja, kita kembali mengambil struktur baru, mengambil templat baru dan mengerjakannya.
Dan jika API sudah usang, jarang diperbarui, atau tidak ada yang mendukungnya, tetapi ada, maka ulangi sedikit sumber daya secara intensif. Kami hanya memutuskan untuk membiarkannya sampai selesai, tetapi ketika sumber daya muncul, kami pasti akan kembali kepada mereka, kami akan melakukan semua ini dengan baik dan indah.
Apa manfaat dari penyatuan? Itu harus jelas bagi semua orang:
"UX", kami berpikir untuk membuat pengguna merasa betah dalam dokumentasi kami. Dia datang, dan tahu apa yang dijelaskan di bagian di mana dia dapat menemukan otorisasi, contoh penggunaan, deskripsi pena. Ini bagus.
Untuk penulis teknologi, deskripsi teknologi memungkinkan Anda untuk menentukan titik masuk tertentu di mana dia datang, dan mulai berkenalan dengan teknologi ini, jika dia tidak mengetahuinya, mulai memahami terminologi, terjun ke dalamnya.
Poin selanjutnya adalah pertukaran. Jika penulis teknologi pergi berlibur atau hanya berhenti menulis, maka penulis teknologi lain, ketika memasukkan dokumen, tahu cara kerjanya di dalam. Segera menghapus apa yang dijelaskan dalam koneksi, di mana mencari informasi tentang integrasi SDK. Memahami dan membuat revisi kecil ke dokumen menjadi lebih mudah. Jelas bahwa setiap proyek memiliki spesifiknya sendiri, Anda tidak bisa datang dan mendokumentasikan beberapa proyek tanpa mengetahuinya sepenuhnya. Tetapi pada saat yang sama, strukturnya, yaitu, navigasi file, akan kira-kira sama.
Dan, tentu saja, terminologi umum. Terminologi yang kami susun untuk bahasa, kami sepakat dengan pengembang dan penerjemah. Kami mengatakan bahwa kami memiliki C #, ada istilah seperti itu, kami menggunakannya dengan cara itu. Kami bertanya kepada pengembang terminologi apa yang mereka gunakan dan ingin mencapai sinkronisasi di tempat ini. Kami memiliki perjanjian, dan pada saat kami datang dengan dokumentasi, para pengembang tahu bahwa kami telah menyetujui persyaratan dan panduan dengan mereka, kami menggunakan template ini, dan mempertimbangkan nuansa penggunaannya. Dan para penerjemah, pada gilirannya, tahu bahwa kami menggambarkan SDK dalam C # atau Objective-C, jadi terminologi ini akan sesuai dengan apa yang dijelaskan dalam panduan ini.
Panduan ditulis dalam halaman wiki, jadi jika bahasa, teknologi, protokol diperbarui, ini semua dengan mudah ditambahkan ke dokumen yang ada. Idyll.
Semakin cepat Anda mulai menyatukan dan menyetujui, semakin baik. Lebih baik maka tidak ada warisan dokumentasi, yang ditulis dalam gaya yang berbeda, yang memecah aliran pengguna dalam dokumentasi. Lebih baik lakukan semuanya sebelumnya.
Menarik pengembang. Ini adalah orang-orang yang Anda tuliskan dokumentasi. Jika Anda sendiri menulis semacam panduan, mungkin mereka tidak akan menyukainya. Lebih baik setuju dengan mereka sehingga Anda memiliki pemahaman yang sama tentang terminologi: apa yang Anda tulis dalam dokumentasi, bagaimana Anda menulisnya.
Dan juga bernegosiasi dengan penerjemah, mereka semua harus menerjemahkannya. Jika mereka menerjemahkan secara berbeda dari yang biasa dilakukan oleh para pengembang, akan ada lagi konflik. (
Berikut ini tautan ke fragmen video dengan pertanyaan dan jawaban - kira-kira. Ed.) Kami beralih.
Julia:
- Hai, nama saya Julia, saya sudah bekerja di Yandex selama lima tahun dan saya mendokumentasikan API dan SDK di grup Andrey. Biasanya semua orang berbicara tentang pengalaman yang baik, betapa hebatnya itu. Saya akan memberi tahu Anda bagaimana kami memilih strategi yang tidak sepenuhnya berhasil. Pada waktu itu, tampaknya berhasil, tetapi kemudian kenyataan pahit datang, dan kami sedikit tidak beruntung.
Kami awalnya memiliki beberapa SDK seluler, dan semuanya ditulis terutama dalam dua bahasa: Objective-C dan Java. Kami menulis dokumentasi kepada mereka secara manual. Seiring waktu, kelas, protokol, dan antarmuka tumbuh. Semakin banyak dari mereka, dan kami menyadari bahwa kami perlu mengotomatiskan bisnis ini, kami melihat apa itu teknologi.

Pada saat itu, kami menyukai Doxygen, memenuhi kebutuhan kami, seperti yang terlihat bagi kami, dan kami memilihnya sebagai generator tunggal. Dan kami menggambar skema seperti itu, yang kami harapkan akan didapat, kami ingin mengerjakannya entah bagaimana.
Apa yang kita miliki Penulis teknis mulai bekerja, menerima kode sumber dari pengembang, mulai menulis komentarnya, diedit, setelah itu dokumentasi harus dikirim ke devserver kami, di sana kami menjalankan Doxygen, menerima format XML, tetapi tidak sesuai dengan standar XML DITA kami. Kami tahu tentang ini sebelumnya, menulis konverter tertentu.
Setelah kami mendapatkan output dari Doxygen, kami melewati semuanya melalui konverter, dan sudah mendapatkan format kami. Kemudian pengumpul dokumentasi terhubung, dan kami menerbitkan semua ini di domain eksternal. Kami bahkan beruntung beberapa iterasi, semuanya berhasil bagi kami, kami senang. Tapi kemudian ada yang tidak beres. Penulis teknis juga mulai bekerja, menerima tugas dan kode sumber dari pengembang, dan membuat koreksi di sana. Setelah itu, dia pergi ke devserver, meluncurkan Doxygen, dan ada api.
Kami memutuskan untuk mencari tahu apa masalahnya. Kemudian kami menyadari bahwa Doxygen tidak cocok untuk semua bahasa. Kami harus menganalisis kode, yang menjadi sandungannya, kami menemukan konstruk yang Doxygen tidak mendukung dan tidak berencana untuk mendukung.
Kami memutuskan, karena kami bekerja dalam skema ini, kami akan menulis skrip preprocessing, dan kami entah bagaimana akan mengganti konstruksi ini dengan apa yang diterima Doxygen, atau entah bagaimana mengabaikannya.

Siklus kami mulai terlihat seperti ini. Kami menerima sumber, memasukkannya ke devserver, kemudian menghubungkan skrip preprocessing, memotong semua kelebihan dari kode, kemudian Doxygen memasuki bisnis, kami menerima format output Doxygen, juga meluncurkan konverter, menerima file XML DITA akhir kami, kemudian kolektor dokumentasi terhubung, dan Kami menerbitkan dokumentasi kami di domain eksternal. Tampaknya semuanya terlihat baik. Menambahkan skrip, ada apa di sana? Awalnya, tidak ada apa-apa. Ada tiga baris dalam naskah, lalu lima, sepuluh baris, dan semuanya berkembang menjadi ratusan baris. Kami menyadari bahwa kami mulai menghabiskan sebagian besar waktu kami bukan untuk menulis dokumentasi, tetapi untuk menganalisis kode, mencari apa yang tidak merangkak di mana, dan hanya menambahkan skrip ke pelanggan tetap yang tak ada habisnya, duduk untuk kegilaan dan memikirkan apa masalahnya.
Kami menyadari bahwa kami perlu mengubah sesuatu, entah bagaimana berhenti, sebelum terlambat, dan sampai siklus rilis kami berakhir sampai akhir.
Sebagai contoh, skrip preprocessing terlihat seperti ini pada awalnya, dan tidak berbahaya.

Mengapa kami awalnya memilih jalur ini? Kenapa dia tampak baik?

Satu generator bagus, mengambilnya, menghubungkannya sekali, mengaturnya dan berfungsi. Sepertinya pendekatan yang bagus. Selain itu, Anda dapat menggunakan sintaks komentar tunggal untuk semua bahasa sekaligus. Anda menulis semacam panduan, menggunakannya sekali, segera masukkan semua konstruksi ini ke dalam kode dan lakukan pekerjaan Anda, tulis komentar, dan jangan lakukan entah bagaimana memperbaiki sintaks.

Tapi ini ternyata menjadi salah satu minus besar. Para pengembang tidak mendukung sintaksis umum kami, mereka terbiasa menggunakan IDE mereka, sudah ada generator asli di sana, dan sintaksis mereka tidak cocok dengan kami. Ini adalah batu sandungan.
Doxygen juga kurang mendukung fitur baru dalam bahasa. Dia memiliki pendekatan selektif, karena dia sendiri ditulis dalam bahasa C ++, dia terutama mendukung bahasa seperti-C, dan sisanya sesuai dengan prinsip residual. Dan bahasa sedang diperbaiki, Doxygen tidak cukup mengikuti mereka, dan itu menjadi sangat tidak nyaman bagi kita.
Kemudian kemalangan terjadi. Sebuah tim baru datang kepada kami dan mengatakan bahwa kami menulis di Swift, dan Doxygen sama sekali tidak berteman dengannya. Kami menyadari bahwa semuanya adalah waktu untuk berhenti dan menghasilkan sesuatu yang baru. Kemudian beberapa tim datang, dan kami menyadari bahwa skema kami tidak dapat ditingkatkan sama sekali. Dan kami terus menambahkan sesuatu, kami memiliki beberapa skrip ini, mereka tinggal di cabang yang berbeda dan hanya itu. Kami menyadari bahwa kami perlu menerima apa yang tidak beruntung, mencoba pendekatan dan solusi baru untuk menemukan. Andrey akan memberi tahu Anda tentang mereka.
“Kami menyadari bahwa dalam kasus kami, di suatu tempat generator universal muncul, tetapi sebagian besar, ketika kami mulai mengukur semuanya, rencana itu tidak berhasil. Mereka muncul dengan dingin, setuju dengan semua orang bahwa mari kita lakukan, tetapi tidak berhasil.
Hasilnya, kami mulai membuat skema baru. Dia bersama generator asli. Apa yang kita miliki di sirkuit sekarang? ( , ), , Objective-C Java, , .

, DITA XML, , , , XML. HTML, . — JavaDoc, AppleDoc, Jazzy. HTML, . HTML, , . , HTML . , , , HTML, . XML , . .
.
— . Doxygen , , . Objective-C, , Java . . , , IDE , IntelliSense, , , , SDK, , . .
, , SDK , , , , HTML, . , , , , , .
. , - , . XML , XML . Doxygen , XML . HTML, XML . . — .
, , . 1500 , : HTML, CSS, .
, , .
. (
— . .)
, , .
— . , . -, . , . ? .
? -, , , , .
- , - , . .
? -, , , , .
. , , , , , , , .
, . , , , , , , .
? — , , , , , . . Bitbucket, - . , .

, . . - , - , , , , , , . , , , , .

, , .
, SDK , - , , . -, , , , .
, . . — , , .
, . . .
, , , , , , .

, .
. - , . .

, , , , . . , , , - . , . , , .
, .
. , . , , .
, , , — . , , , .

dev , (fork-dev) , . , doc-dev-en, . , , - , , .
(fork-dev) (doc-dev-ru) . , - . . , , doc-dev-ru, . , , - , .
, . (doc-dev-en). , , (doc-dev-en), , . , (fork-dev). , , , , . , , . , dev . , , , .
(fork-dev), , . (fork-dev), , (doc-dev-en), . , , , . , .

, , . dev, (fork-dev) , (doc-dev-ru) (doc-dev-en) . (doc-dev-en), (doc-dev-ru) . , .

. dev , , (branch-dev). (branch-dev-ru), (branch-dev). , . , . — , — - , , , , .
, , . , , (branch-dev) . , , .
dev. , , , , . .
(branch-dev-ru), , (branch-dev-ru), . .
. (branch-dev), . , , , , , , , , . , , . , , .

, , , , . .
, ? , , . . . , - , . . , .
, , , , , .
, . . . . , , .
— — . — .
. . , . , , , , , , . .
, . . . . , . , . - , . — . .
Proses harus sama nyamannya bagi semua orang. Karena itu, kami tidak memiliki kediktatoran, kami datang ke pengembang dan berkata: mari kita bekerja melalui brunch. Dan mereka mengatakan bahwa mereka bekerja melalui garpu. Kami mengatakan: baik, tetapi mari kita sepakat bahwa kita juga bekerja melalui garpu. Penting untuk menyetujui sehingga setiap orang yang terlibat dalam proses ini - dalam pelokalan, penulisan kode dan dokumentasi dalam kode - memiliki posisi yang disepakati. Sangat nyaman ketika semua orang memahami bidang tanggung jawab mereka - dan tidak sehingga penulis teknis bekerja dengan mata tertutup dan tidak melihat kode atau tidak memiliki akses ke repositori. Itu saja.