- Penamaan dan keputusan pemodelan resource API adalah bagian yang paling sulit dan paling penting dalam desain API. Resource membentuk model mental pengguna tentang cara kerja dan fungsi produk.
- Tim Increase menggunakan prinsip "tanpa abstraksi" untuk mendukung desain API.
Pendekatan desain API Stripe
- Sebagian besar tim Increase sebelumnya pernah bekerja di Stripe, dan mereka mempertimbangkan nilai desain API sukses dari Stripe.
- Stripe sangat unggul dalam mengekstraksi fungsi inti dari domain yang kompleks menjadi abstraksi yang mudah dipahami dan digunakan pengguna. (Contoh:
PaymentIntent, yang mengabstraksikan perbedaan antara Visa dan Mastercard)
- Sebagian besar pengguna Stripe adalah startup tahap awal yang membangun produk yang tidak terkait pembayaran, sehingga mereka tidak perlu mengetahui detail kartu kredit. Mereka ingin mengintegrasikan Stripe dengan cepat dan fokus pada pengembangan produk.
Pengguna Increase dan prinsip desain API
- Sebaliknya, pengguna Increase memiliki pengetahuan mendalam tentang jaringan pembayaran, dan alasan mereka memilih Increase adalah karena koneksi jaringan langsung dan kedalaman integrasinya.
- Mereka ingin mengetahui dengan tepat kapan jendela FedACH ditutup dan kapan transfer dilakukan, serta memahami bahwa pengaturan SEC code yang berbeda pada transfer ACH dapat memengaruhi waktu pengembalian.
- Upaya untuk menyembunyikan kompleksitas mendasar dari jaringan-jaringan ini tidak akan menyederhanakan hidup pengguna, melainkan hanya membuat mereka frustrasi.
- Melalui percakapan dengan pengguna awal, mereka merumuskan prinsip "tanpa abstraksi" dan menerapkannya pada desain API.
Dampak prinsip "tanpa abstraksi" pada desain API
- Menggunakan istilah yang benar-benar dipakai: alih-alih menciptakan nama sendiri untuk resource dan properti API, mereka menggunakan kosakata dari jaringan dasar. (Contoh: parameter transfer ACH menggunakan nama field dari spesifikasi Nacha)
- Immutability: dengan memakai kejadian nyata sebagai model, lebih banyak resource API dibuat immutable. Mengelompokkan cluster resource immutable ke dalam objek "lifecycle" state machine terbukti efektif. (Contoh: field
status pada objek ach_transfer dan beberapa subobjek immutable yang dibuat sesuai siklus hidup transfer)
- Memisahkan resource berdasarkan use case: ketika himpunan tindakan yang dapat diambil pengguna sangat berbeda tergantung pada instance resource, resource tersebut dipecah menjadi beberapa resource. (Contoh: transfer ACH keluar dan transfer ACH masuk dipisahkan menjadi resource yang berbeda)
Kepatuhan pendekatan oleh tim engineering
- Tim engineering berkomitmen untuk mematuhi pendekatan ini.
- Saat mendesain API yang kompleks selama bertahun-tahun, keputusan inkremental kecil harus terus diambil. Dengan berkomitmen sebelumnya untuk mematuhi prinsip dasar, beban kognitif untuk keputusan-keputusan ini berkurang.
- Sebagai contoh, untuk field Input Message Accountability Data yang diperlukan saat mengirim dana ke Federal Reserve, pada API yang sangat banyak abstraksi orang harus memikirkan cara memberi nama field ini agar "ramah pengguna", tetapi di Increase engineer cukup menamainya
input_message_accountability_data dan melanjutkan.
Opini GN⁺
- Tingkat abstraksi API dapat berbeda tergantung pada tingkat pengalaman developer terhadap domain produk tersebut dan energi yang ingin mereka curahkan untuk integrasi. Karena itu, saat mendesain API penting untuk mempertimbangkan tingkat abstraksi yang tepat bagi developer yang akan mengintegrasikannya.
- Jika membangun API dengan tingkat abstraksi tinggi, perlu berpikir matang sebelum menambahkan fitur baru. Sebaliknya, jika membangun API dengan tingkat abstraksi rendah, perlu konsisten dengan pendekatan itu dan menahan godaan untuk menambahkan abstraksi.
- Menggunakan istilah dari jaringan atau protokol dasar apa adanya dapat membantu developer memahami underlying system, tetapi sebaliknya juga bisa menjadi hambatan masuk bagi developer yang baru pertama kali menemuinya. Karena itu, komentar atau dokumentasi yang baik tampaknya penting.
- Memanfaatkan objek immutable dalam desain API dapat efektif untuk menjaga konsistensi data dan mencegah side effect. Namun, di sisi lain hal ini bisa menyulitkan ketika pembaruan data diperlukan, sehingga trade-off perlu dipertimbangkan dengan baik.
- Memisahkan resource berdasarkan use case dapat meningkatkan kompleksitas API, tetapi dalam jangka panjang dapat meningkatkan prediktabilitas. Namun, jika terlalu terperinci, kegunaannya bisa menurun, sehingga penting untuk menemukan tingkat yang tepat.
1 komentar
Komentar Hacker News
Sebaiknya menyediakan API dengan abstraksi tingkat rendah dan API dengan abstraksi tingkat tinggi
Saya suka bagian yang menjelaskan alasan Increase memilih pendekatan yang berbeda
Kemampuan sejati Stripe adalah memahami pelanggannya dan memberikan kesederhanaan yang mereka inginkan
Ini mirip dengan pola desain "Ubiquitous Language" dalam Domain-Driven Design, yang menggunakan istilah yang sama dalam implementasi seperti istilah nyata yang digunakan oleh para ahli domain
Harus menggunakan bahasa yang dapat dipahami oleh ahli domain
Tanpa abstraksi seperti POSIX, aplikasi harus menulis adaptor untuk setiap sistem file yang didukung
Disebutkan bahwa sebagian struktur API dibangun 1:1 berdasarkan spesifikasi yang dikendalikan dari luar
Satu hal yang sulit dimodelkan dengan rapi dalam API pembayaran adalah bahwa skema pembayaran merepresentasikan peran pembayar dan penerima secara berbeda saat pengembalian pembayaran terjadi