Seseorang mengatakan kata arsitektur yang ditakuti dan Anda Bukan-Seorang Arsitek?

Takut ketika seseorang menantang pemahaman Anda tentang kompleksitas komputasi padahal yang Anda coba lakukan hanyalah memasang widget di halaman web? Jangan pernah takut — ini mungkin tidak secanggih atau serumit yang Anda bayangkan.

Arsitektur memiliki reputasi sebagai arsitektur yang tidak dapat didekati, dijaga gerbangnya, dan merupakan “ilmu komputer yang sulit”. Sebagian besar arsitektur perangkat lunak yang Anda temui, untuk aplikasi web skala rata-rata hingga web, sangat mirip. Kami akan membahas dasar-dasar, beberapa jargon, dan beberapa pola arsitektur yang mungkin Anda lihat di mana-mana dalam panduan arsitektur singkat ini untuk non-arsitek dan pemrogram web.

Apa itu server web?

Oke jadi mari kita mulai dengan dasar-dasarnya. “Web”, atau “world wide web” – dalam istilah kuno yang lucu, hanyalah sekumpulan komputer yang terhubung ke internet. Web adalah serangkaian konvensi yang menggambarkan bagaimana “sumber daya” (baca: halaman web) dapat diambil dari komputer-komputer yang terhubung tersebut.

Singkat cerita, “server web”, menerapkan “protokol HTTP” — serangkaian perintah yang dapat Anda kirim ke komputer jarak jauh — yang memungkinkan Anda mengatakan “hei, komputer, kirimkan saya dokumen itu”. Jika ini terdengar familier, itu karena itulah cara kerja browser web Anda.

Saat Anda mengetik www.my-awesome-website.com di browser Anda, kode yang berjalan di komputer Anda membuat "permintaan http" dan mengirimkannya ke server web yang terkait dengan URL (baca: alamat situs web) yang Anda ketikkan di bilah alamat.

Jadi, server web — program yang berjalan di komputer jarak jauh, terhubung ke internet, mendengarkan permintaan dan mengembalikan data saat menerimanya. Fakta bahwa ini berhasil adalah keajaiban kecil dan dibangun di atas DNS (hal yang mengubah situs web-saya.com menjadi alamat IP), dan banyak jaringan, perutean, dan peralihan. Anda mungkin tidak perlu tahu terlalu banyak tentang semua itu secara nyata kecuali Anda mendalaminya.

Ada banyak sekali server web tujuan umum di luar sana — tetapi secara realistis, Anda mungkin hanya akan melihat campuran Apache, NGINX dan Microsoft IIS, bersama dengan beberapa server web khusus tumpukan pengembangan (Node.js melayani dirinya sendiri, begitu pula hal-hal seperti ASP .NET CORE untuk C#, dan HTTP4K untuk Kotlin).

Bagaimana cara kerja HTTP? Dan apakah itu arsitektur?

Jika Anda pernah melakukan pemrograman web apa pun, Anda mungkin setidaknya sedikit familiar dengan HTTP. Itu singkatan dari “The Hyper Text Transfer Protocol”, dan itulah yang dibicarakan browser Anda ketika berbicara dengan server web. Mari kita lihat “pesan permintaan” HTTP mentah sederhana:

GET http://www.davidwhitney.co.uk/ HTTP/1.1
Host: www.davidwhitney.co.uk
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64…
Accept: text/html,application/xhtml+xml,application/xml;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8

Dasar-dasar HTTP mudah dipahami — ada “baris permintaan” wajib — yang merupakan bit pertama dengan kata kerja (salah satu yang paling sering GET, POST, PUT dan HEAD), URL (alamat web) dan versi protokol ( HTTP/1.1). Lalu ada banyak kolom header permintaan opsional — itu saja hal lainnya — anggap ini sebagai informasi tambahan yang Anda berikan ke server web tentang Anda. Setelah header Anda, ada baris kosong, dan isi opsional. Itu HTTP/1.1. Kita sudah selesai di sini. Server akan merespons dalam bentuk yang sama

HTTP/1.1 200 OK
Cache-Control: public,max-age=1
Content-Type: text/html; charset=utf-8
Vary: Accept-Encoding
Server: Kestrel
X-Powered-By: ASP.NET
Date: Wed, 11 Dec 2019 21:52:23 GMT
Content-Length: 8479

<!DOCTYPE html>
<html lang="en">...

Baris pertama adalah kode status, diikuti oleh header dan isi respons. Itu dia. Server web, berdasarkan konten permintaan, dapat mengirimi Anda apa pun yang diinginkannya, dan perangkat lunak yang membuat permintaan tersebut harus dapat menafsirkan responsnya. Ada banyak perbedaan dalam meminta hal yang benar, dan merespons dengan tepat, namun dasarnya sama.

Web adalah implementasi dari pola desain REST — yang merupakan singkatan dari “Representational State Transfer”. Anda akan sering mendengar orang berbicara tentang REST — REST awalnya didefinisikan oleh Roy Fielding dalam disertasi PhD-nya, namun yang lebih penting adalah deskripsi cara kerja HTTP/1.0 pada saat itu, dan didokumentasikan pada saat Fielding bekerja. pada HTTP/1.1.

Jadi webnya RESTful secara default. REST menjelaskan cara kerja HTTP.

Versi pendeknya? URI (alamat web) yang dapat dialamatkan secara unik yang mengembalikan representasi beberapa keadaan yang disimpan pada mesin di suatu tempat (halaman web, dokumen, gambar, dan lain-lain). Bergantung pada apa yang diminta klien, representasi negara bagian tersebut dapat bervariasi.

Jadi itulah HTTP, dan REST, serta gaya arsitektur, semuanya menjadi satu.

Seperti apa arsitektur aplikasi web?

Anda dapat menulis perangkat lunak yang bagus dengan mengikuti banyak pola arsitektur yang berbeda, tetapi kebanyakan orang berpegang pada beberapa pola umum.

“Aplikasi MVC”

MVC — pengontrol tampilan model — adalah pola desain sederhana yang memisahkan logika pemrosesan suatu aplikasi dan presentasinya. MVC benar-benar menjadi sorotan karena keberhasilan Ruby on Rails (meskipun polanya beberapa dekade lebih tua) dan ketika kebanyakan orang mengatakan "MVC" mereka sebenarnya menggambarkan aplikasi MVC "gaya Rails" tempat kode Anda diatur ke dalam beberapa direktori berbeda

/controllers
/models
/views

Rails mempopulerkan penggunaan “konvensi atas konfigurasi” untuk menyatukan semua hal ini, bersama dengan gagasan “perutean” dan default yang masuk akal. Ini dikloning oleh ASP.NET MVC hampir secara grosir, dan hampir semua kerangka MVC lainnya sejak itu.

Sebagai generalisasi yang luas, secara default, jika Anda memiliki URL yang terlihat seperti itu

http://www.mycoolsite.com/Home/Index

Kerangka kerja MVC, menggunakan “rute” – aturan yang menentukan di mana segala sesuatunya dicari – akan mencoba dan menemukan file atau modul “HomeController” (tergantung pada bahasa pemrograman Anda) di dalam direktori pengontrol. Fungsi yang disebut “Indeks” mungkin ada. Fungsi tersebut akan mengembalikan model — beberapa data — yang dirender oleh “view” — template HTML dari folder views.

Semua kerangka kerja melakukan hal ini sedikit berbeda, namun ide intinya tetap sama — fitur-fitur dikelompokkan berdasarkan pengontrol, dengan fungsi untuk mengembalikan halaman data dan menangani masukan dari web.

“Aplikasi Satu Halaman dengan API

SPA sangat umum dan dipopulerkan oleh kerangka web sisi klien seperti Angular, React, dan Vue.js. Satu-satunya perbedaan nyata di sini adalah kami menggunakan aplikasi MVC dan mengalihkan sebagian besar pekerjaan yang dilakukannya ke sisi klien.

Ada beberapa varian di sini — ada MVC sisi klien, ada MVVM (model-view-view-model), dan ada pemrograman reaktif fungsional (FRP). Perbedaannya mungkin tampak tidak kentara pada awalnya.

Angular adalah kerangka kerja MVC sisi klien — mengikuti pola “model, tampilan, dan pengontrol” — kecuali sekarang ia berjalan di dalam browser web pengguna.

React - sebuah implementasi pemrograman reaktif fungsional - sedikit lebih fleksibel tetapi lebih berkaitan dengan peristiwa perubahan status dalam data - sering kali menggunakan beberapa penyimpanan peristiwa seperti Redux untuk datanya.

MVVM juga umum terjadi pada aplikasi satu halaman di mana terdapat ikatan dua arah antara sesuatu yang menyediakan data (model) dan UI (yang dilayani oleh model tampilan).

Di bawah semua kerangka kerja JavaScript berat klien ini, umumnya terdapat API yang terlihat hampir tidak dapat dibedakan dari "aplikasi MVC", namun alih-alih mengembalikan halaman yang telah dirender sebelumnya, ia mengembalikan data yang "diikat" oleh klien ke UI-nya.

“Situs Statis yang Dihosting di CDN atau server bodoh lainnya”

Mungkin yang paling aneh — ada kebangkitan situs web statis di usia remaja 20-an. Lihat, menskalakan situs web untuk lalu lintas tinggi itu sulit jika Anda terus menjalankan kode di komputer Anda.

Kami menghabiskan waktu bertahun-tahun untuk membangun sistem pengelolaan konten yang relatif rumit dan berkinerja buruk (seperti WordPress), yang memerlukan banyak uang dan perangkat keras untuk dikembangkan.

Sebagai reaksinya, memindahkan rendering konten ke latihan “waktu pengembangan” memiliki manfaat biaya dan skalabilitas yang berbeda. Jika tidak ada kode yang berjalan, kode tersebut tidak akan crash!

Jadi generator situs statis menjadi semakin populer — biasanya memungkinkan Anda menggunakan tumpukan pengembang web front-end biasa, tetapi kemudian membuat semua file menggunakan alat pembangunan untuk digabungkan dan didistribusikan ke server web atau CDN yang bodoh. Lihat alat seperti — Gatsby, Hugo, Jekyll, Wyam.

“Sesuatu yang lain”

Terdapat artipe lain yang diikuti oleh aplikasi web — ada tren yang perlahan meningkat dalam kerangka kerja transpilasi (Blazor untuk C# di WebAssembly, dan target kompilasi javascript Kotlin) — namun dengan popularitas besar kerangka kerja javascript yang dominan pada saat itu, semuanya mencoba untuk memainkannya berjalan dengan baik.

Mengapa saya memilih salah satu dari yang lain?

Pertanyaan rumit. Sejujurnya, sebagian besar ini adalah masalah selera, dan semuanya merupakan cara yang tepat untuk membangun aplikasi web.

Aplikasi MVC yang dirender di server bagus untuk situs web dengan interaktivitas rendah. Meskipun frontend dengan ketelitian tinggi adalah tren yang sedang berkembang, ada banyak sekali kategori situs web yang hanya itu — situs web, bukan aplikasi web — dan biaya kompleksitas dari rangkaian alat yang besar sering kali tidak sebanding dengan investasi yang dikeluarkan.

Apa pun yang memerlukan UX fidelitas tinggi, hampir secara default sekarang, mungkin adalah aplikasi React, Angular, atau Vue. Model pemrograman bekerja dengan baik untuk pengalaman pengguna yang responsif, dan jika Anda tidak menggunakannya, Anda akan menciptakannya kembali sendiri.

Situs statis? Cocok untuk blog, situs mikro pemasaran, sistem manajemen konten, apa pun yang interaksinya paling berharga adalah konten sebenarnya. Skalanya bagus, pada dasarnya tidak bisa crash, dan murah untuk dijalankan.

API HTTP, Istirahat, GraphQL, Backend-untuk-Frontends

Anda pasti akan berinteraksi dengan API, dan meskipun ada banyak istilah yang dilontarkan untuk membuat hal ini terdengar rumit, namun intinya sederhana. Sebagian besar API yang Anda gunakan, atau buat akan bersifat “REST-ish”.

Anda akan mengeluarkan “permintaan HTTP” yang sama seperti yang dilakukan browser Anda, sebagian besar mengembalikan respons JSON (meskipun terkadang XML). Aman untuk mendeskripsikan sebagian besar API ini sebagai JSON-RPC atau XML-RPC.

Pada pergantian milenium ada dorongan untuk standarisasi API “SOAP” (protokol akses objek sederhana), dan meskipun hal itu disertai dengan banyak hal bagus, orang-orang menganggap XML rumit untuk dibaca dan popularitasnya berkurang.

Ironisnya, banyak hal yang diselesaikan dalam SOAP (format amplop pesan yang konsisten, pertimbangan keamanan, verifikasi skema) kemudian harus “diselesaikan kembali” di atas JSON menggunakan standar terbuka seperti Swagger (sekarang OpenAPI) dan JSON:API.

Kami pandai menciptakan kembali hal-hal yang sudah kami miliki di web.

Jadi, apa yang membuat REST API menjadi REST API, dan bukan JSON-RPC?

Saya senang Anda tidak bertanya.

REST pada intinya adalah tentang operasi pemodelan yang dapat terjadi pada sumber daya melalui HTTP. Ada buku bagus karya Jim Webber berjudul Rest in Practice jika Anda ingin mendalami lebih dalam mengapa REST adalah gaya arsitektur yang bagus (dan memang demikian, banyak penolakan modern tentang REST relatif kurang informasi dan tidak terlalu berbeda dengan perlakuan yang dimiliki SOAP. sebelum itu).

Orang-orang sangat peduli dengan apa yang ada dan apa yang bukan REST, dan Anda mungkin akan membuat marah orang-orang yang benar-benar peduli dengan REST, dengan menggambarkan JSON-RPC sebagai REST. JSON-RPC adalah “level 0” dari Richardson Maturity Model — model yang menggambarkan kualitas desain REST. Jangan terlalu khawatir tentang hal itu, karena Anda dapat membangun JSON-RPC yang RESTish, waras, dan layak dengan melakukan beberapa hal.

Pertama, Anda perlu menggunakan HTTP VERBs dengan benar, GET untuk mengambil (dan tidak pernah dengan efek samping), POST untuk “melakukan operasi”, PUT untuk “membuat hal-hal yang keadaannya dikontrol oleh klien”. Setelah itu, pastikan Anda mengatur API Anda ke dalam “sumber daya” yang logis — konsep domain inti Anda “pelanggan”, “produk”, “katalog”, dll.

Terakhir, gunakan kode respons HTTP yang benar untuk interaksi dengan API Anda.

Anda mungkin tidak menggunakan "hypermedia sebagai mesin status aplikasi", tetapi Anda mungkin akan melakukannya dengan cukup baik sehingga tidak ada yang akan datang mengambil darah Anda.

Anda juga akan mendapatkan banyak manfaat dari RESTful API sepenuhnya hanya dengan melakukan hal yang cukup — sumber daya akan dapat dinavigasi melalui HTTP, dokumen Anda akan dapat disimpan dalam cache, API Anda akan berfungsi di sebagian besar alat umum. Gunakan pustaka swagger atau OpenAPI untuk menghasilkan skema dan Anda melakukan apa yang dilakukan kebanyakan orang.

Tapi saya membaca di hackernews bahwa REST sux dan GraphQL adalah pilihan yang tepat?

Ya, kita semua juga membaca postingan itu.

GraphQL membingungkan, Bahasa Kueri, standar untuk API HTTP, dan alat Skema sekaligus. Dengan berkembangnya aplikasi web yang banyak di sisi klien, GraphQL telah mendapatkan popularitas dengan secara efektif mendorong definisi data apa yang harus dikembalikan ke klien, ke dalam kode klien itu sendiri.

Ini bukan pertama kalinya pendekatan gaya “kueri dari front end” seperti ini disarankan, dan kemungkinan besar bukan yang terakhir. Apa yang sedikit membedakan GraphQL dari pendekatan sebelumnya (terutama OData Microsoft) adalah gagasan bahwa Jenis dan Kueri diimplementasikan dengan kode Resolver di sisi server, bukan hanya memetakan langsung ke beberapa penyimpanan SQL.

Hal ini berguna karena beberapa alasan — artinya GraphQL dapat berupa API tunggal di atas sekumpulan API yang berbeda di domain Anda, ini memecahkan masalah “pengambilan berlebih” yang cukup umum di REST API dengan mengizinkan klien menentukan subset data yang mereka coba kembalikan, dan juga bertindak sebagai semacam lapisan anti-korupsi, mencegah akses tak terbatas ke penyimpanan yang mendasarinya.

GraphQL juga dirancang untuk menjadi satu-satunya titik koneksi yang digunakan oleh web atau aplikasi seluler Anda, yang sangat berguna untuk mengoptimalkan kinerja — sederhananya, lebih cepat jika satu API melalui kabel memanggil API hilir dengan latensi lebih rendah, dibandingkan aplikasi seluler Anda memanggil (pada latensi tinggi) semua API internal itu sendiri.

GraphQL sebenarnya hanyalah cara cerdas dan efektif untuk membuat skema API Anda, dan menyediakan BFF — yang merupakan backend untuk frontend, bukan sahabat selamanya — yang dapat berubah dengan cepat.

sahabat? Apa sebenarnya BFF itu?

Bayangkan masalah ini — Anda bekerja untuk MEGACORP yang memiliki seratus tim, atau regu (Anda tidak ingat, mereka mengganti nama nomenklaturnya setiap dua minggu sekali) — masing-masing bertanggung jawab atas serangkaian layanan mikro.

Anda seorang pemrogram web yang mencoba menyelesaikan beberapa pekerjaan, dan fitur baru baru saja diluncurkan. Anda membaca dokumennya.

Dokumen tersebut menjelaskan bagaimana Anda harus mengatur panggilan antara beberapa API, semuanya memerlukan token OAuth, dan klaim, dan pada akhirnya, Anda akan memiliki fitur baru yang menarik.

Jadi Anda menulis panggilan API, dan Anda menyadari bahwa waktu yang diperlukan untuk terus mengirimkan data ke dan dari klien, apalagi risiko keamanan karena harus memeriksa apakah semua data aman untuk transit, memperlambat Anda hingga terhenti. Inilah sebabnya mengapa Anda membutuhkan sahabat selamanya.

Maaf, backend untuk front-end.

BFF adalah API yang melayani satu, dan khususnya hanya satu aplikasi. Ini menerjemahkan domain internal (MEGACORPS BUSINESS), ke dalam bahasa internal aplikasi yang dilayaninya. Ini menangani hal-hal seperti otentikasi, pembatasan kecepatan, hal-hal yang tidak ingin Anda lakukan lebih dari sekali. Ini mengurangi perjalanan bolak-balik yang tidak perlu ke server, dan menerjemahkan data agar lebih sesuai untuk aplikasi targetnya.

Anggap saja sebagai API, hanya untuk aplikasi Anda, yang Anda kendalikan.

Dan alat seperti GraphQL, dan OData sangat bagus untuk BFF. GraphQL sangat cocok dengan ujung depan berbasis JavaScript modern, dengan alat luar biasa seperti Apollo dan Apollo-Server yang membantu mengoptimalkan panggilan ini dengan mengelompokkan permintaan.

Ini juga cukup ramah front-end-dev — kueri dan skema sangat mirip dengan json, dan menjaga tumpukan Anda “javascript sepenuhnya” tanpa terikat pada tim backend jauh.

Hal lain yang mungkin Anda lihat dan alasannya

Jadi sekarang kami memahami server web, aplikasi web, dan API kami, pasti ada lebih banyak hal dalam pemrograman web modern selain itu? Berikut hal-hal yang mungkin paling sering Anda temui.

Penyeimbang beban

Jika Anda cukup beruntung memiliki lalu lintas ke situs Anda, namun cukup beruntung karena tidak menggunakan penyedia Platform-as-a-Service (lebih lanjut tentang itu nanti), Anda akan mengalami penyeimbang beban di beberapa titik. Jangan panik. Penyeimbang beban menggunakan bahasa kuno, sering kali dioperasikan oleh pengurus yang pemarah, atau hanya menjalankan salinan NGINX.

Yang dilakukan penyeimbang beban hanyalah menerima permintaan HTTP untuk aplikasi Anda (atau dari aplikasi tersebut), memilih server yang tidak terlalu sibuk, dan meneruskan permintaan tersebut.

Anda dapat membuat penyeimbang beban melakukan segala macam hal gila yang mungkin tidak seharusnya Anda gunakan untuk penyeimbang beban. Orang-orang akan tetap mencoba.

Anda mungkin melihat penyeimbang beban memuat penyeimbangan “jalur panas” tertentu dalam perangkat lunak Anda ke kumpulan perangkat keras khusus untuk mencoba menjaganya tetap aman atau mengisolasinya dari kegagalan. Anda mungkin juga melihat penyeimbang beban yang digunakan untuk menangani sertifikat SSL untuk Anda — ini disebut Penghentian SSL.

Cache terdistribusi

Jika satu komputer dapat menyimpan beberapa data dalam memori, maka banyak komputer dapat menyimpan… yah, lebih banyak data!

Caching terdistribusi dipelopori oleh “Memcached” — awalnya ditulis untuk menskalakan platform blogging Livejournal pada tahun 2003. Pada saat itu, Memcached membantu Livejournal membagikan salinan cache dari semua entri terbaru, di sejumlah server yang relatif kecil, sehingga sangat mengurangi beban server database. perangkat keras yang sama.

Cache memori digunakan untuk menyimpan hasil dari sesuatu yang “berat” untuk dihitung, membutuhkan waktu, atau hanya perlu konsisten di semua komputer berbeda yang menjalankan perangkat lunak server Anda. Sebagai imbalan atas sedikit latensi jaringan, jumlah total memori yang tersedia untuk aplikasi Anda akan menjadi jumlah seluruh memori yang tersedia di seluruh server Anda.

Caching terdistribusi juga sangat berguna untuk mencegah “penyerbuan cache” — ketika cache yang tidak terdistribusi gagal, dan data yang di-cache akan dihitung ulang oleh semua klien, namun dengan berbagi memori mereka, kemungkinan kegagalan cache penuh berkurang secara signifikan, dan bahkan ketika itu terjadi, hanya sebagian data yang akan dihitung ulang.

Cache terdistribusi ada di mana-mana, dan semua penyedia hosting utama cenderung mendukung cache terkelola yang kompatibel dengan memcached atau redis (baca: Anda dapat menggunakan pustaka klien memcached untuk mengaksesnya).

Memahami cara kerja cache terdistribusi sangatlah sederhana — saat item ditambahkan, kunci (yang Anda gunakan untuk mengambil item tersebut) yang dihasilkan mencakup alamat atau nama komputer yang menyimpan data tersebut di cache. Menghasilkan kunci pada komputer mana pun yang merupakan bagian dari cluster cache terdistribusi akan menghasilkan kunci yang sama.

Ini berarti bahwa ketika perpustakaan klien yang berinteraksi dengan cache digunakan, mereka memahami komputer mana yang harus mereka panggil untuk mengambil data.

Memecah kumpulan besar memori bersama seperti ini adalah tindakan yang cerdas, karena hal ini membuat pencarian sesuatu menjadi sangat cepat — tidak ada satu komputer pun yang perlu memindai memori dalam jumlah besar untuk mengambil item.

Jaringan Pengiriman Konten (CDN)

CDN adalah server web yang dijalankan oleh orang lain, di seluruh dunia. Anda mengunggah data Anda ke mereka, dan mereka akan mereplikasi data Anda di semua “tepi” mereka (istilah konyol yang berarti “ke semua server di seluruh dunia yang mereka jalankan”) sehingga ketika seseorang meminta konten Anda, Respons DNS akan mengembalikan server yang dekat dengan mereka, dan waktu yang diperlukan untuk mengambil konten tersebut akan jauh lebih cepat.

Mekanisme pengoperasian CDN jauh lebih rumit dibandingkan menggunakan CDN — namun CDN adalah pilihan tepat jika Anda memiliki banyak aset statis (gambar!) atau terutama file besar (video! binari besar!). Mereka juga sangat berguna untuk mengurangi keseluruhan beban di server Anda.

Membongkar ke CDN adalah salah satu cara termudah untuk mendapatkan kinerja ekstra dengan biaya yang sangat minimal.

Mari kita bicara tentang pola desain! Itu adalah arsitektur yang sebenarnya

“Design patterns are just bug fixes for your programming languages”

Orang-orang akan berbicara tentang pola desain seolah-olah itu adalah cawan suci - tetapi pola desain adalah jawaban atas masalah yang sering dipecahkan orang, dan ada cara yang dapat diterima untuk menyelesaikannya. Jika bahasa, alat, atau kerangka kerja kita lebih baik, mereka mungkin akan melakukan tugasnya untuk kita (dan faktanya, fitur dan alat bahasa yang lebih baru sering kali membuat pola desain menjadi usang seiring berjalannya waktu).

Mari kita lihat sekilas beberapa hal yang sangat umum:

  • MVC — “Pisahkan model data, kode UI, dan logika bisnis Anda, agar tidak bingung”
  • ORM — “Pemetaan Objek-Relasional” — Gunakan pustaka pemetaan dan aturan yang dikonfigurasi, untuk mengelola penyimpanan objek dalam memori Anda, ke dalam penyimpanan relasional. Jangan mengacaukan objek dan tempat Anda menyimpannya”.
  • Catatan Aktif — “Semua objek Anda seharusnya dapat disimpan sendiri, karena ini hanyalah formulir web, siapa yang peduli jika objek tersebut terkait dengan database!”
  • Repositori — “Semua akses data Anda ada di kelas ini — berinteraksilah dengannya untuk memuat sesuatu.”
  • Dekorator — “Tambahkan atau gabungkan 'dekorator' di sekitar objek, kelas, atau fungsi untuk menambahkan perilaku umum seperti cache, atau logging tanpa mengubah implementasi aslinya.”
  • Injeksi Ketergantungan — “Jika kelas atau fungsi Anda bergantung pada sesuatu, pemanggil (seringkali kerangka kerja yang Anda gunakan) bertanggung jawab untuk menyediakan ketergantungan tersebut”
  • Pabrik — “Letakkan semua kode yang Anda perlukan untuk membuat salah satunya, di satu tempat, dan hanya di satu tempat”
  • Adaptor — “Gunakan adaptor untuk menjembatani kesenjangan antara hal-hal yang tidak dapat berfungsi bersama — menerjemahkan representasi data internal ke representasi data eksternal. Seperti mengubah tanggapan Twitter menjadi YourSocialMediaDataStructure”
  • Perintah — “Setiap tindakan atau permintaan terpisah, diterapkan di satu tempat”
  • Strategi — “Tentukan berbagai cara untuk melakukan sesuatu yang dapat ditukar masuk dan keluar”
  • Singleton — “Hanya ada satu yang seperti ini di seluruh lamaran saya”.

Itu adalah daftar tidak lengkap dari beberapa jargon pola yang akan Anda dengar. Tidak ada yang istimewa tentang pola desain, itu hanyalah jawaban stackoverflow versi tahun 1990-an yang diterima dan populer.

Arsitektur layanan mikro

Arsitektur layanan mikro hanyalah “gelombang ketiga” dari Desain Berorientasi Layanan.

Dari mana asalnya?

Pada pertengahan tahun 90an, “COM+” (Layanan Komponen) dan SOAP populer karena mengurangi risiko penerapan sesuatu, dengan membaginya menjadi komponen-komponen kecil — dan menyediakan cara standar dan relatif sederhana untuk berkomunikasi melintasi batas-batas proses. Hal ini menyebabkan mempopulerkan arsitektur “3-tier” dan kemudian “n-tier” untuk sistem terdistribusi.

N-Tier sebenarnya merupakan singkatan dari “memisahkan tingkat data, tingkat logika bisnis, dan tingkat presentasi”. Hal ini berhasil bagi sebagian orang — namun mengalami masalah karena irisan horizontal pada suatu sistem sering kali memerlukan perubahan setiap “tingkatan” untuk menyelesaikan perubahan penuh. Efek riak ini buruk bagi keandalan.

Vendor produk kemudian terlibat, dan SOAP menjadi rumit dan ketinggalan jaman, yang mendorong orang menuju “gelombang kedua” – Gerilya SOA. Desain serupa, tanpa upacara besar, irisan vertikal yang lebih lengkap, dan middleware vendor yang lebih sedikit.

Hal ini menyebabkan berkembangnya layanan yang lebih kecil dan lebih gesit, sekitar waktu yang sama ketika Netflix mempromosikan hystrix — platform mereka untuk sistem latensi dan toleransi kesalahan.

Gelombang ketiga SOA, yang diberi nama arsitektur Microservice (oleh James Lewis dan Martin Fowler) — sangat populer, tetapi mungkin tidak terlalu dipahami.

Apa yang seharusnya menjadi Layanan Mikro: Layanan kecil, berguna secara independen, dapat diversi secara independen, dan dapat dikirimkan secara independen yang menjalankan fungsi atau operasi domain tertentu.

Yang sering terjadi pada Microservices adalah: Layanan yang rapuh, saling bergantung, dan rabun yang bertindak sebagai objek akses data melalui HTTP yang sering gagal seperti domino.

Desain layanan mikro yang baik mengikuti beberapa aturan sederhana

  • Berbasis peran/operasi, bukan berpusat pada data
  • Selalu miliki penyimpanan data Anda
  • Berkomunikasi pada antarmuka atau pesan eksternal
  • Apa yang berubah bersama-sama, dan saling bergantung, sebenarnya adalah hal yang sama
  • Semua layanan toleran terhadap kesalahan dan bertahan jika ketergantungannya terputus

Layanan mikro yang tidak menunjukkan kualitas tersebut kemungkinan besar hanyalah monolit yang didistribusikan secara rahasia. Tidak apa-apa, banyak orang mengoperasikan monolit terdistribusi dalam skala besar, tetapi Anda akan merasakan kesulitannya pada suatu saat.

Arsitektur Heksagonal

Sekarang ini terdengar seperti “Real Architecture TM”!

Arsitektur heksagonal, juga dikenal sebagai pola “port dan adaptor” — seperti yang didefinisikan oleh Alistair Cockburn, adalah salah satu saran terbaik dari “arsitektur aplikasi nyata”.

Sederhananya — miliki semua logika, aturan bisnis, hal-hal khusus domain — ada dalam bentuk yang tidak terikat dengan kerangka kerja, dependensi, penyimpanan data, bus pesan, repositori, atau UI Anda.

Semua “barang luar” itu, “disesuaikan” dengan model internal Anda, dan dimasukkan ke dalamnya bila diperlukan.

Seperti apa sebenarnya bentuknya? Semua logika Anda ada dalam file, modul, atau kelas yang bebas dari kode kerangka kerja, lem, atau akses data eksternal.

Mengapa? Artinya, Anda dapat menguji semuanya secara terpisah, tanpa kerangka web atau API rusak yang menghalangi. Menjaga logika Anda tetap bersih dari semua masalah eksternal ini adalah cara aman untuk merancang aplikasi.

Ada pendekatan kedua yang cukup populer yang digambarkan sebagai "Aplikasi Dua Belas Faktor" - yang sebagian besar memiliki tujuan desain yang sama, dengan beberapa aturan preskriptif yang diterapkan di atasnya.

Penskalaan

Penskalaan sulit dilakukan jika Anda mencoba melakukannya sendiri, jadi jangan mencoba melakukannya sendiri.

Gunakan abstraksi cloud yang disediakan vendor seperti Google App Engine, Azure Web Apps, atau AWS Lambda dengan dukungan penskalaan otomatis diaktifkan jika Anda mungkin dapat menghindarinya.

Pertimbangkan untuk menempatkan API Anda pada tumpukan tanpa server. Semakin jauh abstraksi yang Anda peroleh, penskalaan akan semakin mudah.

Kebijakan konvensional mengatakan bahwa “peningkatan skala adalah satu-satunya hal yang hemat biaya”, namun banyak perusahaan sukses yang berhasil melakukan peningkatan skala dengan beberapa mesin atau VM berukuran besar. Peningkatan skala memberi Anda manfaat lain (sering kali terkait dengan distribusi geografis, atau ketahanan lintas zona ketersediaan) namun jangan merasa sedih jika satu-satunya yang keluar dari Anda adalah yang diberi label “lebih banyak kekuatan”.

Pola arsitektur untuk sistem terdistribusi

Membangun sistem terdistribusi lebih sulit daripada hanya membangun satu aplikasi. Tidak ada yang benar-benar membicarakan hal itu, tapi memang begitu. Akan lebih mudah bagi sesuatu untuk gagal jika Anda membagi semuanya menjadi bagian-bagian kecil, namun kecil kemungkinannya Anda akan gagal total jika Anda melakukannya dengan benar.

Ada beberapa hal yang selalu berguna.

Pemutus Sirkuit di mana-mana

Pemutusan sirkuit adalah pola sistem terdistribusi yang berguna di mana Anda memodelkan koneksi keluar seolah-olah itu adalah sirkuit listrik. Dengan mengukur keberhasilan panggilan melalui sirkuit tertentu, jika panggilan mulai gagal, Anda “mematikan sekring”, mengantri permintaan keluar daripada mengirim permintaan yang Anda tahu akan gagal.

Setelah beberapa saat, Anda membiarkan satu permintaan mengalir melalui sirkuit (keadaan “setengah terbuka”), dan jika berhasil, Anda “menutup” sirkuit lagi dan membiarkan semua permintaan yang diantrekan mengalir.

Pemutus sirkuit adalah cara yang fenomenal untuk memastikan Anda tidak gagal ketika Anda tahu hal itu mungkin terjadi, dan mereka juga melindungi layanan yang sedang berjuang agar tidak dilupakan oleh panggilan Anda.

Anda akan lebih bersyukur atas pemutus sirkuit Anda ketika Anda menyadari bahwa Anda adalah pemilik API yang Anda panggil.

Idempotensi dan Percobaan Ulang

Pola desain pelengkap untuk semua pemutus sirkuit Anda — Anda perlu memastikan bahwa Anda menggabungkan semua koneksi keluar dalam kebijakan percobaan ulang, dan back-off.

Apa artinya ini? Anda harus merancang panggilan Anda agar tidak merusak jika Anda mengirimkannya dua kali (idempotensi), dan jika Anda memiliki panggilan yang dikonfigurasi untuk mencoba kembali kesalahan, mungkin Anda mundur sedikit (jika tidak secara eksponensial) ketika kegagalan berulang terjadi — paling tidak untuk memberikan waktu pada hal yang Anda panggil untuk pulih.

Sekat

Sekat terinspirasi dari sekat fisik yang ada di kapal selam. Ketika bagian dari lambung kapal selam rusak, sekatnya akan tertutup, mencegah sisa kapal selam dari banjir. Ini analogi yang sangat keren, dan ini semua tentang isolasi.

Sumber daya, kapasitas, atau perangkat keras fisik yang dicadangkan dapat dilindungi untuk bagian perangkat lunak Anda, sehingga pemadaman di satu bagian sistem Anda tidak berdampak pada bagian lain.

Anda dapat menetapkan batas konkurensi maksimum untuk panggilan tertentu dalam sistem multithread, memanfaatkan batas waktu dengan bijaksana (lebih baik menggunakan batas waktu, daripada mengunci dan terjatuh), dan bahkan mencadangkan perangkat keras atau kapasitas untuk fungsi bisnis penting (seperti pembayaran, atau pembayaran).

Arsitektur yang digerakkan oleh peristiwa dengan log replay/pesan

Arsitektur berbasis peristiwa/pesan sering kali tangguh, karena panggilan masuk yang dirancang tidak sinkron. Dengan menggunakan peristiwa yang di-buffer dalam antrean, sistem Anda dapat mendukung pemadaman, peningkatan dan penurunan skala, serta peningkatan berkelanjutan tanpa pertimbangan khusus apa pun. Mode operasi normalnya adalah “membaca dari antrean”, dan ini tidak berubah dalam keadaan luar biasa.

Jika digabungkan dengan pola konsumen yang bersaing — di mana beberapa prosesor berlomba untuk mengonsumsi pesan dari antrean — maka akan mudah untuk memperluas skala demi mendapatkan kinerja yang baik dengan arsitektur yang digerakkan oleh antrean dan peristiwa.

Apakah saya memerlukan Kubernetes untuk itu?

Tidak. Anda mungkin tidak mengalami masalah penskalaan yang sama seperti Google.

Dengan mempopulerkan buruh pelabuhan dan container, ada banyak sensasi yang muncul pada hal-hal yang menyediakan abstraksi “hampir seperti platform” atas Infrastruktur sebagai Layanan. Ini semua adalah kerja keras dan mahal.

Jika Anda bisa mengelolanya dengan cara apa pun, gunakan hal yang paling dekat dengan platform yang dikelola murni sebisa mungkin. Azure App Services, Google App Engine, dan AWS Lambda akan jauh lebih produktif bagi Anda sebagai programmer. Mereka akan lebih mudah dioperasikan dalam produksi, dan lebih mudah dijelaskan dan didukung.

Kubernetes (sering disingkat menjadi k8s, bersama dengan ekosistem luar biasa yang terdiri dari tambahan-tambahan yang diberi nama esoteris seperti helm, dan flux) memerlukan tim operasi penuh waktu untuk beroperasi, dan bahkan dalam “mode vendor terkelola” di EKS/AKS/GKS, kurva pembelajarannya adalah jauh lebih curam dibandingkan alternatif lainnya.

Pahlawanku? Layanan Aplikasi? Mesin Aplikasi? Itu adalah hal-hal yang dapat Anda siapkan sendiri, untuk produksi, dalam hitungan menit hingga hanya beberapa jam.

Anda akan melihat tekanan untuk mendorong solusi “Cloud neutral” menggunakan Kubernetes di berbagai tempat — namun hal ini tidaklah mudah. Menjadi cloud netral berarti Anda membayar biaya migrasi cloud (mempertahankan abstraksi, mengisolasi fitur khusus vendor yang berguna) secara terus-menerus, bukan dalam skenario (yang sangat tidak mungkin terjadi) saat Anda berpindah vendor cloud.

Penggunaan teknologi secara bertanggung jawab mencakup penggunaan hal yang paling sesuai dengan masalah dan skala yang Anda miliki.

Rekomendasi yang Masuk Akal

Selalu lakukan hal paling sederhana yang mungkin berhasil. Arsitektur mempunyai biaya, sama seperti setiap abstraksi. Anda harus yakin bahwa Anda mendapatkan manfaatnya sebelum menyelami beberapa pola arsitektur yang rumit.

Seringkali, arsitektur terbaik adalah yang paling sederhana dan paling mudah diubah.